from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
- 连接
Base = declarative_base()
engine = create_engine('postgresql://midwaredata:[email protected]:5433/qhinfo', echo=True)
echo为True的时候,会显示每一条执行的sql语句
create_engine
用来初始化数据库连接,sqlalchemy
用一个字符串表示连接信息:
'数据库类型+数据库驱动://用户名:密码@机器地址:端口/数据库名'
DBSession = sessionmaker(bind=engine)
session = DBSession()
- 声明映像
使用Declarative
方法定义的映射类依据一个基类,这个基类是维系类和数据表关系的目录,在一个普通的模块入口中,应用通常只需要一个base
的实例。通过declarative_base()
创建一个基类:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
有了这个base
,就可以依据这个base
定义任意数量的映射类,每一个类对应一张数据库表,一个简单的user
类:
from sqlclchemy import Column, Integer, String
class User(Base):
__table__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
用
Declarative
构造的一个类至少需要一个__tablename__
属性,一个主键行。
- 创建映射类的实例(数据表中的一行):
new_user = User(id=3, name='zhul')
- 创建会话
现在准备和数据库开始会话,ORM通过Session与数据库建立连接,当应用第一次载入时,我们定义一个Session类(声明create_engine()的同时):
from sqlalchemy.orm import sessionmaker
DBSession = sessionmaker(bind=engine)
这个定制的DBSession类会创建绑定到数据库的DBSession对象,如果需要和数据库建立连接,只需要实例化一个DBSession:
session = DBSession()
虽然上面的DBSession已经和数据库引擎engine关联,但是还没有打开任何连接。当它第一次被使用时,就会从engine维护的一个连接池中检索是否存在连接,如果存在便会保持连接直到我们提交所有更改或者关闭session对象。
- 添加新对象
session.add(new_user)
至此,我们可以认为,新添加的这个对象实例仍在等待中,new_user对象现在并不代表数据库中的一行数据,直到使用flush进程,session才会让SQL保持连接,如果查询这条数据的话,所有等待信息会被第一时间刷新,查询结果也会立即发出。
session.commit()
使用commit方法将所有更改提交到数据库。
- 回滚
session.rollback()
- 查询
通过session的query()方法创建一个查询对象,这个函数的参数数量是可变的,参数可以是任何类或者是类的描述的集合,下面是迭代输出User类的例子:
for instance in session.query(User).order_by(User.id):
print instance.name
Query也支持ORM描述作为参数。任何时候,多个类的实体或者是基于列的实体表达都可以作为query()函数的参数,返回类型是元组:
for id, name in session.query(User.id, User.name):
print id, name
Query返回的元组被命名为KeyedTuple类的实例元组。并且可以把它当做一个普通的Python数据类操作,元组的名字就相当于属性的属性名,类的类名一样。
for row in session.query(User, User.name).all():
查询条件筛选filter
- 等值筛选
session.query(User).filter(User.id == 1)
- 模糊查询
for i in session.query(User).filter(User.name.like('%zhul%')):
print i.id, i.name
- 范围条件(in/not in)
for i in session.query(User).filter(User.id.in_([1, 2, 3])):
print i.name
for i in session.query(User).filter(~User.id.in_([1, 2, 3])):
print i.name
- 空值条件
session.query(User).filter(User.name == None)
session.query(User).filter(User.name.is_(None))
session.query(User).filter(User.name != None)
session.query(User).filter(User.name.isnot(None))
- 并且条件(AND)
from sqlalchemy import and_
session.query(User).filter(User.name=='tom').filter(User.id==1)
session.query(User).filter(User.name=='tom', User.id==1)
session.query(User).filter(and_(User.name=='tom', User.id==1))
- 或者条件(OR)
session.query(User).filter(or_(User.name=='tom', User.id==1))
- sql语句查询
from sqlalchemy import text
session.query(User).from_statement(
test('select * from users where name=:name and id=:id')).params(name='tom', id=1).all()