本篇所有操作均在基于 Ubuntu 16.04 LTS 的虚拟机下完成,且使用 Vagrant 来操作虚拟机系统,虚拟机系统 VirtualBox Version: 7.0
一、使用 ORM
环境准备:
Python 2.7.11+
pip==9.0.3
flask==0.11.1
httpie==0.9.4
werkzeug==0.11.10
1、sessionmaker 创建会话
ORM 是基于 SQLAlchemy 表达式语言的,如下代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# coding=utf-8
from sqlalchemy import create_engine, Column, Integer, String, Sequence
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import and_, or_
from sqlalchemy.orm import sessionmaker
from consts import DB_URI # 导入数据库连接配置
eng = create_engine(DB_URI) # 配置数据库
Base = declarative_base() # 构造基类
class User(Base):
"""定义的 User 类会生成一张表,__tablename__ 的值就是表名"""
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'),
primary_key=True, autoincrement=True) # Sequence`object 表示数据库序列的名称和配置参数。
name = Column(String(50))
Base.metadata.drop_all(bind=eng) # 删除全部表(实际工作时不要这样用)
Base.metadata.create_all(bind=eng) # 创建多个表
# 通过 sessionmaker 创建一个会话与数据库建立连接,会话提供了事务控制的支持
Session = sessionmaker(bind=eng)
session = Session()
"""
session.add_all() 可以将给定的模型实例对象的集合加入到会话中
因为模型实例对象本身独立存在,若想要其修改(创建)生效,需要将它们加入某个会话;
若不想生效则去掉由 session 管理的实例对象
"""
session.add_all([User(name=username)
for username in ('xiaoming', 'wanglang', 'lilei')])
session.commit() # 修改被提交到数据库
# session.rollback # 回滚变更
def get_result(rs):
print '-' * 20
for user in rs:
print user.name
# 示例一、查询表 users 中全部的记录
rs = session.query(User).all()
get_result(rs)
# 示例二、查询 id 包含 [2, ] 的记录,此处查询 id=2。若为 [2, 3, 4] 则查询 id=2,id=3,id=4 的记录
rs = session.query(User).filter(User.id.in_([2, ]))
get_result(rs)
# 示例三、查询 id>2 and id<4 的记录
rs = session.query(User).filter(and_(User.id > 2, User.id < 4))
get_result(rs)
# 示例四、查询 id=2 or id=4 的记录
rs = session.query(User).filter(or_(User.id == 2, User.id == 4))
get_result(rs)
# 示例五、模糊查询 like
rs = session.query(User).filter(User.name.like('%min%'))
get_result(rs)
# 示例六、查询 name='xiaoming' 的记录
user = session.query(User).filter_by(name='xiaoming').first()
get_result([user])
2、query 条件查询语句
如上代码所示,使用 create_engine() 配置数据库,使用 sessionmaker() 创建会话与数据库建立连接,使用 session.create_all() 将模型实例对象的修改加入会话并通过 session.commit() 提交。数据库中表 users 已有三条记录 'xiaoming', 'wanglang', 'lilei'
,现在进行表的查询,使用如下有条件的简单查询语句:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 示例一、查询表 users 中全部的记录
rs = session.query(User).all()
get_result(rs)
# 示例二、查询 id 包含 [2, ] 的记录,此处查询 id=2。若为 [2, 3, 4] 则查询 id=2,id=3,id=4 的记录
rs = session.query(User).filter(User.id.in_([2, ]))
get_result(rs)
# 示例三、查询 id>2 and id<4 的记录
rs = session.query(User).filter(and_(User.id > 2, User.id < 4))
get_result(rs)
# 示例四、查询 id=2 or id=4 的记录
rs = session.query(User).filter(or_(User.id == 2, User.id == 4))
get_result(rs)
# 示例五、模糊查询 like
rs = session.query(User).filter(User.name.like('%min%'))
get_result(rs)
# 示例六、查询 name='xiaoming' 的记录
user = session.query(User).filter_by(name='xiaoming').first()
get_result([user])
查询结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
--------------------
xiaoming
wanglang
lilei
--------------------
wanglang
--------------------
lilei
--------------------
wanglang
--------------------
xiaoming
--------------------
xiaoming
3、text 复杂条件查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# coding=utf-8
from sqlalchemy import create_engine, Column, Integer, String, Sequence, text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from consts import DB_URI
eng = create_engine(DB_URI)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'),
primary_key=True, autoincrement=True)
name = Column(String(50))
Base.metadata.drop_all(bind=eng)
Base.metadata.create_all(bind=eng)
Session = sessionmaker(bind=eng)
session = Session()
session.add_all([User(name=username)
for username in ('xiaoming', 'wanglang', 'lilei')])
session.commit()
def get_result(rs):
print '-' * 20
for user in rs:
print user.name
# 使用 text() 直接输入 SQL 语句,使用 params() 进行关键字传参,使用 order_by() 进行如下正序排序
rs = session.query(User).filter(
text('id > 2 and id < 4')).order_by(text('id')).all()
get_result(rs)
rs = session.query(User).filter(text('id<:value and name=:name')).params(
value=3, name='xiaoming').all()
get_result(rs)
rs = session.query(User).from_statement(
text('SELECT * FROM users where name=:name')).params(name='wanglang').all()
get_result(rs)
查询结果如下:
1
2
3
4
5
6
--------------------
lilei
--------------------
xiaoming
--------------------
wanglang
二、ORM 三种排序方式
1、order_by()
order_by 可以指定根据这个表中的某个字段进行排序,如果前面加上一个 -
代表是降序排序。查询时使用 order_by,如果想要倒序显示必须 desc() 方法指定。
(1)正序排序
1
2
3
4
返回的查询对象集 = session.query(模型类).order_by(模型类.字段名).all()
如:
rs = session.query(User).order_by(User.id).all()
(2)倒序排序
1
2
3
4
5
6
返回的查询对象集 = session.query(模型类).order_by(模型类.字段名.desc()).all()
返回的查询对象集 = session.query(模型类).order_by(-模型类.字段名).all()
如:
rs = session.query(User).order_by(User.id.desc()).all()
rs = session.query(User).order_by(-User.id).all()
2、mapper_args
定义模型类时,使用 __mapper_args__={"order_by": 字段}
指定排序方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
class Article(Base):
__tablename__ = "article"
id = Column(Integer, autoincrement=True, primary_key=True)
title = Column(String(20), nullable=False)
create_time = Column(DateTime, nullable=False,default=datetime.now)
__mapper_args__ = {
"order_by":id.desc()
}
def __repr__(self):
return "<id:%s>" % self.id
3、relationship 指定参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class User(Base):
__tablename__ = 'user
id = Column (Integer, primary_key=True, autoincrement=True)
username = Column(String(50), nullable=False)
class Article(Base):
__tablename__ = 'article'
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(50), nullable=False)
create time = Column(DateTime, nullable=False, default=datetime.now)
uid = Column(Integer, ForeignKey('user.id'))
author = relationship("User", backref=backref("articles", order_by=create_time.desc()))
相关链接:
ORM-三种排序方式