Peewee 教程展示了如何使用 Python Peewee ORM。
对象关系映射(ORM)是一种从面向对象的语言访问关系数据库的技术。 它是 Python 数据库 API 的抽象。
Python Peewee
Peewee 是一个简单而小型的 Python ORM 工具。 它支持 SQLite,MySQL 和 PostgreSQL。
$ pipenv install peewee
我们安装peewee模块。
Peewee 映射
Model映射到数据库表,Field映射到表列,instance映射到表行。
Peewee 对于 MySQL 使用MySQLDatabase,对于 PostgreSQL 使用PostgresqlDatabase,对于 SQLite 使用SqliteDatabase。 在本教程中,我们将使用 SQLite 数据库。
Peewee 字段类型
Peewee 模型中的字段类型定义模型的存储类型。 它们被转换为相应的数据库列类型。
| 字段类型 | SQLite | PostgreSQL | MySQL |
|---|---|---|---|
CharField |
varchar |
varchar |
varchar |
TextField |
text |
text |
longtext |
DateTimeField |
datetime |
timestamp |
longtext |
IntegerField |
integer |
integer |
integer |
BooleanField |
smallint |
bool |
bool |
FloatField |
real |
real |
real |
DoubleField |
real |
double |
double |
BigIntegerField |
integer |
bigint |
bigint |
DecimalField |
decimal |
numeric |
numeric |
PrimaryKeyField |
integer |
serial |
integer |
ForeignKeyField |
integer |
integer |
integer |
DateField |
date |
date |
date |
TimeField |
time |
time |
time |
下表列出了 Peewee 字段类型以及相应的 SQLite,PostgreSQL 和 MySQL 列类型。
Peewee 模型定义
在第一个示例中,我们创建一个简单的数据库表。
model_definition.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'Note.create_table()note1 = Note.create(text='Went to the cinema')note1.save()note2 = Note.create(text='Exercised in the morning',created=datetime.date(2018, 10, 20))note2.save()note3 = Note.create(text='Worked in the garden',created=datetime.date(2018, 10, 22))note3.save()note4 = Note.create(text='Listened to music')note4.save()
该示例在 SQLite 中创建notes数据库表。
db = peewee.SqliteDatabase('test.db')
我们启动test.db SQLite 数据库。 这将在文件系统上创建一个test.db文件。
class Note(peewee.Model):...
我们定义了一个名为Note的数据库模型。 Peewee 模型继承自peewee.Model。
text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)
我们指定模型字段。 我们有一个CharField和一个DateField。 CharField是用于存储字符串的字段类。 DateField是用于存储日期的字段类。 如果未指定,则采用默认值。
class Meta:database = dbdb_table = 'notes'
在Meta类中,我们定义对数据库的引用和数据库表名称。
Note.create_table()
该表是使用create_table()从模型创建的。
note1 = Note.create(text='Went to the cinema')note1.save()
我们创建并保存一个新实例。
sqlite> select * from notes;1|Went to the cinema|2018-11-012|Exercised in the morning|2018-10-203|Worked in the garden|2018-10-224|Listened to music|2018-11-01
我们验证数据。
Peewee 删除表
使用drop_table()模型方法删除该表。
drop_table.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'Note.drop_table()
该示例删除notes表。
Peewee insert_many
insert_many()方法允许进行批量创建。
insert_many.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'Note.create_table()data = [{ 'text': 'Tai chi in the morning', 'created': datetime.date(2018, 10, 20) },{ 'text': 'Visited friend', 'created': datetime.date(2018, 10, 12) },{ 'text': 'Went to cinema', 'created': datetime.date(2018, 10, 5) },{ 'text': 'Listened to music', 'created': datetime.date(2018, 10, 28) },{ 'text': 'Watched TV all day', 'created': datetime.date(2018, 10, 14) },{ 'text': 'Worked in the garden', 'created': datetime.date(2018, 10, 22) },{ 'text': 'Walked for a hour', 'created': datetime.date(2018, 10, 28) }]with db.atomic():query = Note.insert_many(data)query.execute()
该代码示例通过一次批量创建操作来重新创建notes表。
data = [{ 'text': 'Tai chi in the morning', 'created': datetime.date(2018, 10, 20) },{ 'text': 'Visited friend', 'created': datetime.date(2018, 10, 12) },{ 'text': 'Went to cinema', 'created': datetime.date(2018, 10, 5) },{ 'text': 'Listened to music', 'created': datetime.date(2018, 10, 28) },{ 'text': 'Watched TV all day', 'created': datetime.date(2018, 10, 14) },{ 'text': 'Worked in the garden', 'created': datetime.date(2018, 10, 22) },{ 'text': 'Walked for a hour', 'created': datetime.date(2018, 10, 28) }]
我们在字典列表中定义数据。
with db.atomic():query = Note.insert_many(data)query.execute()
我们执行批量操作。 atomic()方法将批量操作置于事务中。
Peewee 选择所有实例
select()方法用于检索定义的模型的实例。
fetch_all.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'notes = Note.select()for note in notes:print('{} on {}'.format(note.text, note.created))
该示例获取并显示所有Note实例。
notes = Note.select()
select()方法创建一个SELECT查询。 如果未明确提供任何字段,则查询将默认选择模型上定义的所有字段。
$ ./fetch_all.pyTai chi in the morning on 2018-10-20Visited friend on 2018-10-12Went to cinema on 2018-10-05Listened to music on 2018-10-28Watched TV all day on 2018-10-14Worked in the garden on 2018-10-22Walked for a hour on 2018-10-28
这是输出。
Peewee where过滤器
where()方法可以根据给定条件过滤数据。
where_clause.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'notes = Note.select().where(Note.id > 3)for note in notes:print('{} {} on {}'.format(note.id, note.text, note.created))
该示例检索 ID 大于三的所有行。
notes = Note.select().where(Note.id > 3)
where()方法对查询应用过滤条件。
$ ./where_clause.py4 Listened to music on 2018-10-285 Watched TV all day on 2018-10-146 Worked in the garden on 2018-10-227 Walked for a hour on 2018-10-28
这是输出。
Peewee 多个where表达式
我们可以组合多个where表达式。
multiple_where_expr.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'notes = Note.select().where((Note.id > 2) & (Note.id < 6))for note in notes:print('{} {} on {}'.format(note.id, note.text, note.created))
该示例检索id大于 2 且小于 6 的所有行。
notes = Note.select().where((Note.id > 2) & (Note.id < 6))
我们将两个where表达式与&运算符结合使用。
$ ./multiple_where_expr.py3 Went to cinema on 2018-10-054 Listened to music on 2018-10-285 Watched TV all day on 2018-10-14
这是输出。
Peewee 检索单个实例
选择单个实例有两种方法: 它们每个都使用get()方法。
single_instance.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'note1 = Note.select().where(Note.text == 'Went to cinema').get()print(note1.id)print(note1.text)print(note1.created)note2 = Note.get(Note.text == 'Listened to music')print(note2.id)print(note2.text)print(note2.created)
该示例显示了如何以两种方式检索单个实例。
note1 = Note.select().where(Note.text == 'Went to cinema').get()
我们可以使用Note.select().where().get()方法链。
note2 = Note.get(Note.text == 'Listened to music')
还有一个Note.get()快捷方式,其功能相同。
$ ./single_instance.py3Went to cinema2018-10-054Listened to music2018-10-28
这是输出。
Peewee 选择特定的列
在select()方法内部,我们可以指定要包含在查询中的列的名称。
columns.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'notes = Note.select(Note.text, Note.created).limit(2)output = [e for e in notes.tuples()]print(output)
该示例包括两列:text和created。 该 ID 被跳过。 我们将查询限制为两个实例。
$ ./columns.py[('Tai chi in the morning', datetime.date(2018, 10, 20)),('Visited friend', datetime.date(2018, 10, 12))]
这是输出。
Peewee 计数实例
要计算表中的模型实例数,我们可以使用count()方法。
count_instances.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'n = Note.select().count()print(n)n2 = Note.select().where(Note.created >= datetime.date(2018, 10, 20)).count()print(n2)
该示例计算所有实例的数量以及日期等于或晚于2018/10/20的实例的数量。
$ ./count_instances.py74
这是输出。
Peewee 显示 SQL 语句
可以使用sql()方法显示生成的 SQL 语句。
show_sql.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'note3 = Note.select().where(Note.id == 3)print(note3.sql())
该示例显示将 ORM 查询转换为的 SQL。
$ ./show_sql.py('SELECT "t1"."id", "t1"."text", "t1"."created" FROM "notes" AS "t1"WHERE ("t1"."id" = ?)', [3])
这是输出。
Peewee offset和limit
通过offset和limit属性,我们可以定义实例的初始跳过和要包含在select()中的实例数。
offset_limit.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'notes = Note.select().offset(2).limit(3)for note in notes:print(note.id, note.text, note.created)
该示例从第二个实例开始返回三个实例。
$ ./offset_limit.py3 Went to cinema 2018-10-054 Listened to music 2018-10-285 Watched TV all day 2018-10-14
这是输出。
Peewee 排序
可以使用order_by()对检索到的实例进行排序。
order_by.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'print('Ascending order')print('*****************************')notes = Note.select(Note.text, Note.created).order_by(Note.created)for note in notes:print(note.text, note.created)print()print('Descending order')print('*****************************')notes = Note.select(Note.text, Note.created).order_by(Note.created.desc())for note in notes:print(note.text, note.created)
该代码示例按创建日期对实例进行排序。
notes = Note.select(Note.text, Note.created).order_by(Note.created)
该行返回按创建日期升序排列的笔记实例。
notes = Note.select(Note.text, Note.created).order_by(Note.created.desc())
要按升序检索笔记,我们在字段上附加desc()方法。
Ascending order*****************************Went to cinema 2018-10-05Visited friend 2018-10-12Watched TV all day 2018-10-14Tai chi in the morning 2018-10-20Worked in the garden 2018-10-22Listened to music 2018-10-28Walked for a hour 2018-10-28Descending order*****************************Listened to music 2018-10-28Walked for a hour 2018-10-28Worked in the garden 2018-10-22Tai chi in the morning 2018-10-20Watched TV all day 2018-10-14Visited friend 2018-10-12Went to cinema 2018-10-05
这是音符实例的有序列表。
Peewee 删除实例
delete_by_id()方法删除由其 ID 标识的实例。 它返回已删除实例的数量。
delete_by_id.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'n2 = Note.delete_by_id(1)print(n2)
该示例删除一个 ID 为 1 的Note实例。
Peewee 删除多个实例
要删除更多实例,我们调用delete()方法。 它返回成功删除的实例数。
delete_instances.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'query = Note.delete().where(Note.id > 3)n = query.execute()print('{} instances deleted'.format(n))
在此示例中,我们删除了 ID 大于 3 的所有实例。
$ ./delete_instances.py4 instances deleted
在我们的例子中,我们删除了四个Note实例。
Peewee 更新实例
update()方法更新一个实例。 它返回成功更新的实例数。
update_instance.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Note(peewee.Model):text = peewee.CharField()created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'notes'query = Note.update(created=datetime.date(2018, 10, 27)).where(Note.id == 1)n = query.execute()print('# of rows updated: {}'.format(n))
该示例使用 ID 1 修改笔记的创建日期。
Peewee 一对多关系
在以下示例中,我们将模型映射到现有表。 使用ForeignKeyField创建模型之间的关系。
customers_reservations.sql
BEGIN TRANSACTION;DROP TABLE IF EXISTS reservations;DROP TABLE IF EXISTS customers;CREATE TABLE IF NOT EXISTS customers(id INTEGER PRIMARY KEY, name TEXT);INSERT INTO customers(Name) VALUES('Paul Novak');INSERT INTO customers(Name) VALUES('Terry Neils');INSERT INTO customers(Name) VALUES('Jack Fonda');INSERT INTO customers(Name) VALUES('Tom Willis');CREATE TABLE IF NOT EXISTS reservations(id INTEGER PRIMARY KEY,customer_id INTEGER, created DATE,FOREIGN KEY(customer_id) REFERENCES customers(id));INSERT INTO reservations(customer_id, created) VALUES(1, '2018-22-11');INSERT INTO reservations(customer_id, created) VALUES(2, '2018-28-11');INSERT INTO reservations(customer_id, created) VALUES(2, '2018-29-11');INSERT INTO reservations(customer_id, created) VALUES(1, '2018-29-11');INSERT INTO reservations(customer_id, created) VALUES(3, '2018-02-12');COMMIT;
该 SQL 创建两个表:customers和reservations。 两个表之间存在一对多的关系:一个客户可以进行很多预订。
sqlite> .read customers_reservations.sql
我们将 SQL 文件读入数据库。
one2many.py
#!/usr/bin/env python3import peeweeimport datetimedb = peewee.SqliteDatabase('test.db')class Customer(peewee.Model):name = peewee.TextField()class Meta:database = dbdb_table = 'customers'class Reservation(peewee.Model):customer = peewee.ForeignKeyField(Customer, backref='reservations')created = peewee.DateField(default=datetime.date.today)class Meta:database = dbdb_table = 'reservations'customer = Customer.select().where(Customer.name == 'Paul Novak').get()for reservation in customer.reservations:print(reservation.id)print(reservation.created)
在示例中,我们定义了两个映射到表的模型。 然后,我们选择一个客户并显示其预订。
customer = peewee.ForeignKeyField(Customer, backref='reservations')
Customer和Reservation模型之间的关系是通过ForeignKeyField创建的。 backref属性设置了我们如何引用客户的预订。
for reservation in customer.reservations:
客户实例具有reservations属性,其中包含相应的预留。
$ ./one2many.py12018-22-1142018-29-11
这是输出。
在本教程中,我们介绍了 Python Peewee ORM。
您可能也对以下相关教程感兴趣: Python 教程, pyDAL 教程, PyMongo 教程和 PyMySQL 教程。
