1.ORM是什么?
orm就是对象映射关系程序,简单来世就是类似于python这种面向对象的程序来说一切接对象,它可以将我们平常所使用的SQL语句,转换成可以使用对象模型进行操作的模块,而不是直接使用SQL语句.
2.sqlalchemy的安装
pip install SQLALchemy
pip install pymysql
3.sqlalchemy基本使用
CREATE TABLE user (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(32),
password VARCHAR(64),
PRIMARY KEY (id)
)
这是最简单的SQL表如果再加上外键什么的,那就更加复杂了,所以就有了我们的sqlalchemy!
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
engine = create_engine("mysql+pymysql://root:alex3714@localhost/testdb",
encoding='utf-8', echo=True)
Base = declarative_base() #生成orm基类
class User(Base):
__tablename__ = 'user' #表名
id = Column(Integer, primary_key=True)
name = Column(String(32))
password = Column(String(64))
Base.metadata.create_all(engine) #创建表结构
看到这里你可能感觉不出什么,那是因为现在实现的功能比较简单,但是当功能复杂以后,你就会发现这个东西的好处。
这里还有一种创建表的方式,但是不常用
from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey
from sqlalchemy.orm import mapper
metadata = MetaData()
user = Table('user', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(50)),
Column('fullname', String(50)),
Column('password', String(12))
)
class User(object):
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password
mapper(User, user) #the table metadata is created separately with the Table construct, then associated with the User class via the mapper() function
其实第一种就是第二种创建表方式的一种封装
现在来创建一条数据试试
Session_class = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
Session = Session_class() #生成session实例
user_obj = User(name="alex",password="alex3714") #生成你要创建的数据对象
print(user_obj.name,user_obj.id) #此时还没创建对象呢,不信你打印一下id发现还是None
Session.add(user_obj) #把要创建的数据对象添加到这个session里, 一会统一创建
print(user_obj.name,user_obj.id) #此时也依然还没创建
Session.commit() #现此才统一提交,创建数据
查询:
my_user = Session.query(User).filter_by(name="alex").first()
print(my_user)
他输出的是:
<__main__.User object at 0x105b4ba90>
他返回的是一个对象,所以是这个样子,你可以通过调出他里面对象的方式来显示。
print(my_user.id,my_user.name,my_user.password)
输出
1 alex alex3714
不过刚才上面的显示的内存对象对址你是没办法分清返回的是什么数据的,除非打印具体字段看一下,如果想让它变的可读,只需在定义表的类下面加上这样的代码
def __repr__(self):
return "<User(name='%s', password='%s')>" % (
self.name, self.password)
修改
my_user = Session.query(User).filter_by(name="alex").first()
my_user.name = "Alex Li"
Session.commit()
回滚
my_user = Session.query(User).filter_by(id=1).first()
my_user.name = "Jack"
fake_user = User(name='Rain', password='12345')
Session.add(fake_user)
print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #这时看session里有你刚添加和修改的数据
Session.rollback() #此时你rollback一下
print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #再查就发现刚才添加的数据没有了。
# Session
# Session.commit()
获取所有数据
print(Session.query(User.name,User.id).all() )
多条件查询
objs = Session.query(User).filter(User.id>0).filter(User.id<7).all()
上面2个filter的关系相当于 user.id >1 AND user.id <7 的效果
统计和分组
Session.query(User).filter(User.name.like("Ra%")).count()
分组
from sqlalchemy import func print(Session.query(func.count(User.name),User.name).group_by(User.name).all() )
输出为:
[(1, 'Jack'), (2, 'Rain')]
外键关联
创建一个address表,跟user表关联
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String(32), nullable=False)
user_id = Column(Integer, ForeignKey('user.id'))
user = relationship("User", backref="addresses") #这个nb,允许你在user表里通过backref字段反向查出所有它在addresses表里的关联项
def __repr__(self):
return "<Address(email_address='%s')>" % self.email_address
表创建好以后可以反查试试
obj = Session.query(User).first()
for i in obj.addresses: #通过user对象反查关联的addresses记录
print(i)
addr_obj = Session.query(Address).first()
print(addr_obj.user.name) #在addr_obj里直接查关联的user表
创建关联对象
obj = Session.query(User).filter(User.name=='rain').all()[0]
print(obj.addresses)
obj.addresses = [Address(email_address="[email protected]"), #添加关联对象
Address(email_address="[email protected]")]
Session.commit()