开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python 使用 Peewee

Peewee教程展示了如何使用PythonPeeweeORM。

对象关系映射(ORM)是一种从面向对象语言访问关系数据库的技术。它是Python数据库API的抽象。

PythonPeewee

Peewee是一个简单的小型PythonORM工具。它支持SQLite、MySQL和PostgreSQL。

$ pipenv install peewee

我们安装peewee模块。

Peewee映射

Model映射到数据库表,Field映射到表列,instance映射到表行。

Peewee使用MySQLDatabase用于MySQL,PostgresqlDatabase用于PostgreSQL,SqliteDatabase用于SQLite。在本教程中,我们使用SQLite数据库。

Peewee字段类型

Peewee模型中的字段类型定义模型的存储类型。它们被转换为相应的数据库列类型。

字段类型 SQLite PostgreSQL MySQL
CharField varchar varchar varchar
TextField text text longtext
DateTimeField datetime 时间戳 日期时间
IntegerField 整数 整数 整型
BooleanField smallint boolean bool
FloatField 实数 实数 实数
DoubleField 实数 双精度 双精度
BigIntegerField 整数 bigint bigint
DecimalField decimal numeric numeric 数值
PrimaryKeyField 整数 序列号 整数
ForeignKeyField 整数 整数 整数
DateField date 日期 日期
时间字段 时间 时间 时间

此表列出了Peewee字段类型和对应的SQLite、PostgreSQL和MySQL列类型。

Peewee模型定义

在第一个例子中,我们创建了一个简单的数据库表。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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.dbSQLite数据库。这会在文件系统上创建一个test.db文件。

class Note(peewee.Model):
...

我们定义了一个名为Note的数据库模型。Peewee模型继承自peewee.Model

text = peewee.CharField()
created = peewee.DateField(default=datetime.date.today)

我们指定模型字段。我们有一个CharField和一个DateFieldCharField是一个用于存储字符串的字段类。DateField是一个用于存储日期的字段类。如果未指定,则采用默认值。

class Meta:
    database = db
    db_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-01
2|Exercised in the morning|2018-10-20
3|Worked in the garden|2018-10-22
4|Listened to music|2018-11-01

我们验证数据。

Peewee掉落表

使用drop_table模型方法删除表。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:
        database = db
        db_table = 'notes'


Note.drop_table()

该示例删除了notes表。

Peeweeinsert_many

insert_many方法允许批量创建。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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()

代码示例在一次bulkcreate操作中重新创建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方法用于检索已定义模型的实例。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_table = 'notes'


notes = Note.select()

for note in notes:
    print('{} on {}'.format(note.text, note.created))

该示例获取并显示所有Note实例。

notes = Note.select()

select方法创建一个SELECT查询。如果没有明确提供字段,查询将默认选择模型上定义的所有字段。

$ ./fetch_all.py
Tai chi in the morning on 2018-10-20
Visited friend on 2018-10-12
Went to cinema on 2018-10-05
Listened to music on 2018-10-28
Watched TV all day on 2018-10-14
Worked in the garden on 2018-10-22
Walked for a hour on 2018-10-28

带where的Peewee过滤器

where方法可以根据给定的条件过滤数据。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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.py
4 Listened to music on 2018-10-28
5 Watched TV all day on 2018-10-14
6 Worked in the garden on 2018-10-22
7 Walked for a hour on 2018-10-28

Peewee多个where表达式

我们可以组合多个where表达式。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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.py
3 Went to cinema on 2018-10-05
4 Listened to music on 2018-10-28
5 Watched TV all day on 2018-10-14

Peewee检索单个实例

选择单个实例有两种方式;他们每个人都使用get方法。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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.py
3
Went to cinema
2018-10-05
4
Listened to music
2018-10-28

Peewee选择特定列

select方法中,我们可以指定要包含在查询中的列的名称。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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方法。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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.py
7
4

Peewee展示SQL语句

生成的SQL语句可以用sql方法显示。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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偏移量,限制

使用offsetlimit属性,我们可以定义初始跳过的实例和要包含在select中的实例数。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_table = 'notes'

notes = Note.select().offset(2).limit(3)

for note in notes:
    print(note.id, note.text, note.created)

该示例返回三个实例,从第二个实例开始。

$ ./offset_limit.py
3 Went to cinema 2018-10-05
4 Listened to music 2018-10-28
5 Watched TV all day 2018-10-14

Peewee订购

可以使用order_by对检索到的实例进行排序。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db 
        db_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-05
Visited friend 2018-10-12
Watched TV all day 2018-10-14
Tai chi in the morning 2018-10-20
Worked in the garden 2018-10-22
Listened to music 2018-10-28
Walked for a hour 2018-10-28

Descending order
*****************************
Listened to music 2018-10-28
Walked for a hour 2018-10-28
Worked in the garden 2018-10-22
Tai chi in the morning 2018-10-20
Watched TV all day 2018-10-14
Visited friend 2018-10-12
Went to cinema 2018-10-05

这是笔记实例的有序列表。

Peewee删除实例

delete_by_id方法删除由其Id标识的实例。它返回已删除实例的数量。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:
        database = db
        db_table = 'notes'

n2 = Note.delete_by_id(1)
print(n2)

该示例删除了一个ID为1的Note实例。

Peewee删除多个实例

要删除更多实例,我们调用delete方法。它返回成功删除实例的数量。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:
        database = db
        db_table = 'notes'

query = Note.delete().where(Note.id > 3)
n = query.execute()

print('{} instances deleted'.format(n))

在示例中,我们删除了所有Id大于3的实例。

$ ./delete_instances.py
4 instances deleted

在我们的例子中,我们删除了四个Note实例。

Peewee更新实例

update方法更新一个实例。它返回成功更新实例的数量。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Note(peewee.Model):

    text = peewee.CharField()
    created = peewee.DateField(default=datetime.date.today)

    class Meta:
        database = db
        db_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创建的。

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创建两个表:customersreservations。两个表之间存在一对多关系:一个客户可以有多个预订。

sqlite> .read customers_reservations.sql 

我们将SQL文件读入数据库。

#!/usr/bin/python

import peewee
import datetime

db = peewee.SqliteDatabase('test.db')

class Customer(peewee.Model):

    name = peewee.TextField()

    class Meta:

        database = db
        db_table = 'customers'

class Reservation(peewee.Model):

    customer = peewee.ForeignKeyField(Customer, backref='reservations')
    created = peewee.DateField(default=datetime.date.today)

    class Meta:

        database = db
        db_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')

CustomerReservation模型之间的关系是使用ForeignKeyField创建的。backref属性设置我们如何引用客户的预订。

for reservation in customer.reservations:

客户实例有一个属性reservations,其中包含相应的预订。

$ ./one2many.py
1
2018-22-11
4
2018-29-11

在本教程中,我们介绍了PythonPeeweeORM。

访问Python教程或列出所有Python教程。

未经允许不得转载:我爱分享网 » Python 使用 Peewee

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏