SQLalchemy使用补充
1.engine = create_engine(echo=true)
sqlalchemy与数据库通信的命令都将打印出来
1 2018-01-13 09:42:43,634 INFO sqlalchemy.engine.base.Engine show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin' 2 2018-01-13 09:42:43,634 INFO sqlalchemy.engine.base.Engine {} 3 2018-01-13 09:42:43,738 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1 4 2018-01-13 09:42:43,739 INFO sqlalchemy.engine.base.Engine {} 5 2018-01-13 09:42:43,754 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1 6 2018-01-13 09:42:43,754 INFO sqlalchemy.engine.base.Engine {} 7 2018-01-13 09:42:43,756 INFO sqlalchemy.engine.base.Engine SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin AS anon_1 8 2018-01-13 09:42:43,757 INFO sqlalchemy.engine.base.Engine {} 9 2018-01-13 09:42:43,790 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 10 2018-01-13 09:42:43,792 INFO sqlalchemy.engine.base.Engine UPDATE users SET name=(concat(users.name, %(name_1)s)) WHERE users.id > %(id_1)s 11 2018-01-13 09:42:43,792 INFO sqlalchemy.engine.base.Engine {'name_1': '512', 'id_1': 0}
2.声明一个映射(declare a Mapping)
declarative_base
类维持了一个从类到表的关系,通常一个应用使用一个base实例,所有实体类都应该继承此类对象
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base()
3.创建Session
Session是真正与数据库通信的handler,你还可以把他理解一个容器,add就是往容器中添加对象
1 from sqlalchemy.orm import sessionmaker 2 Session = sessionmaker(bind=engine) 3 4 #创建完session就可以添加数据了 5 ed_user = User('ed','Ed jone','edpasswd') 6 session.add(ed_user) 7 8 #也可以使用session.add_all()添加多个对象 9 #session.add_all([user1,user2,user3]) 10 11 print ed_user in session # True 12 session.rollback() 13 print ed_user in session # False
执行完add方法后,ed_user
对象处于pending状态,不会触发INSERT语句,当然ed_uesr.id也为None,如果在add方后有查询(session.query),那么会flush一下,把数据刷一遍,把所有的pending信息先flush再执行query。
4.对象实例有四种状态
Transient(瞬时的):这个状态的对象还不在session中,也不会保存到数据库中,主键为None(不是绝对的,如果Persistent对象rollback后虽然主键id有值,但还是Transient状态的)。
Pending(挂起的):调用session.add()后,Transient对象就会变成Pending,这个时候它还是不会保存到数据库中,只有等到触发了flush动作才会存在数据库,比如query操作就可以出发flush。同样这个时候的实例的主键一样为None
Persistent(持久的):session中,数据库中都有对应的一条记录存在,主键有值了。
Detached(游离的):数据库中有记录,但是session中不存在,对这个状态的对象进行操作时,不会触发任何SQL语句。
5.常用过滤操作
1 equals: 2 query.filter(User.name == 'ed') 3 4 not equal: 5 query.filter(User.name !='ed') 6 7 LIKE: 8 query.filter(User.name.like('%d%') 9 10 IN: 11 query.filter(User.name.in_(['a','b','c']) 12 13 NOT IN: 14 query.filter(~User.name.in_(['ed','x']) 15 16 IS NULL: 17 filter(User.name==None) 18 19 AND: 20 from sqlalchemy import and_ 21 filter(and_(User.name == 'ed',User.fullname=='xxx')) 22 23 或者多次调用filter或filter_by: 24 filter(User.name =='ed').filter(User.fullname=='xx') 25 26 OR: 27 from sqlalchemy import or_ 28 query.filter(or_(User.name == ‘young’, User.name == ‘sun’))
6.查询返回结果
1 query.all(),all()返回列表 2 query.first():返回第一个元素 3 query.one()有且只有一个元素时才正确返回。 4 5 filter函数还可以接收text对象,text是SQL查询语句的字面对象,比如: 6 7 for user in session.query(User).filter(text(“id<20”)).order_by(text(“id”)).all(): 8 print user.name
7.两种count
1 第一种是纯粹是执行SQL语句后返回有多少行,对应的函数count(),第二个是func.count(),适用在分组统计,比如按性别分组时,男的有多少,女的多少: 2 3 session.query(User).filter(User.name==’sun’).count() 4 session.query(func.count(), User.gender).group_by(User.gender).all( )
8.关联查询
primaryjoin:用在一对多或者多对一的关系中,默认情况连接条件就是主键与另一端的外键,用primaryjoin参数可以用来指定连接条件 ,比如:下面user的address必须现address是一'tony'开头:
1 class User(Base): 2 __tablename__ = 'user' 3 id = Column(Integer, primary_key=True) 4 name = Column(String) 5 6 addresses = relationship("Address", 7 primaryjoin="and_(User.id==Address.user_id, " 8 "Address.email.startswith('tony'))", 9 backref="user") 10 11 class Address(Base): 12 __tablename__ = 'address' 13 id = Column(Integer, primary_key=True) 14 email = Column(String) 15 user_id = Column(Integer, ForeignKey('user.id'))