8.1 KiB
peewee 介绍——另一种 Python ORM
原文:https://www.blog.pythonlibrary.org/2014/07/17/an-intro-to-peewee-another-python-orm/
我认为除了 SQLAlchemy 之外,尝试一些不同的 Python 对象关系映射器(ORM)会很有趣。我最近偶然发现了一个名为 peewee 的项目。对于这篇文章,我们将从我的 SQLAlchemy 教程中提取例子,并将其移植到 peewee,看看它是如何站起来的。peewee 项目支持 sqlite、postgres 和 MySQL 开箱即用,虽然没有 SQLAlchemy 灵活,但也不错。你也可以通过一个方便的 Flask-peewee 插件在 Flask web 框架中使用 peewee。
无论如何,让我们开始玩这个有趣的小图书馆吧!
入门指南
首先,你得去找皮威。幸运的是,如果您安装了 pip,这真的很容易:
pip install peewee
一旦安装完毕,我们就可以开始了!
创建数据库
用 peewee 创建数据库非常容易。事实上,在 peewee 中创建数据库比在 SQLAlchemy 中更容易。你所需要做的就是调用 peewee 的 SqliteDatabase 方法,如果你想要一个内存中的数据库,把文件的路径或者“:memory:”传递给它。让我们创建一个数据库来保存我们音乐收藏的信息。我们将创建两个表:艺术家和专辑。
# models.py
import peewee
database = peewee.SqliteDatabase("wee.db")
########################################################################
class Artist(peewee.Model):
"""
ORM model of the Artist table
"""
name = peewee.CharField()
class Meta:
database = database
########################################################################
class Album(peewee.Model):
"""
ORM model of album table
"""
artist = peewee.ForeignKeyField(Artist)
title = peewee.CharField()
release_date = peewee.DateTimeField()
publisher = peewee.CharField()
media_type = peewee.CharField()
class Meta:
database = database
if __name__ == "__main__":
try:
Artist.create_table()
except peewee.OperationalError:
print "Artist table already exists!"
try:
Album.create_table()
except peewee.OperationalError:
print "Album table already exists!"
这段代码非常简单。我们在这里所做的就是创建两个定义表的类。我们设置字段(或列),并通过嵌套类 Meta 将数据库连接到模型。然后我们直接调用这个类来创建表。这有点奇怪,因为您通常不会像这样直接调用一个类,而是创建该类的一个实例。然而,这是根据 peewee 的文档推荐的程序,并且效果很好。现在我们准备学习如何向我们的数据库添加一些数据。
如何向表格中插入/添加数据
事实证明,将数据插入我们的数据库也非常容易。让我们来看看:
# add_data.py
import datetime
import peewee
from models import Album, Artist
new_artist = Artist.create(name="Newsboys")
album_one = Album(artist=new_artist,
title="Read All About It",
release_date=datetime.date(1988,12,01),
publisher="Refuge",
media_type="CD")
album_one.save()
albums = [{"artist": new_artist,
"title": "Hell is for Wimps",
"release_date": datetime.date(1990,07,31),
"publisher": "Sparrow",
"media_type": "CD"
},
{"artist": new_artist,
"title": "Love Liberty Disco",
"release_date": datetime.date(1999,11,16),
"publisher": "Sparrow",
"media_type": "CD"
},
{"artist": new_artist,
"title": "Thrive",
"release_date": datetime.date(2002,03,26),
"publisher": "Sparrow",
"media_type": "CD"}
]
for album in albums:
a = Album(**album)
a.save()
bands = ["MXPX", "Kutless", "Thousand Foot Krutch"]
for band in bands:
artist = Artist.create(name=band)
artist.save()
这里我们调用该类的 create 方法来添加乐队或唱片。该类也支持一个 insert_many 方法,但是每当我试图通过 save() 方法保存数据时,我都会收到一个 OperationalError 消息。如果你碰巧知道如何做到这一点,请在评论中给我留言,我会更新这篇文章。作为一种变通方法,我只是循环遍历一个字典列表,并以这种方式添加记录。
更新:《peewee》的作者在 reddit 上回复了我,给了我这个一次添加多条记录的解决方案:
albums = [{"artist": new_artist,
"title": "Hell is for Wimps",
"release_date": datetime.date(1990,07,31),
"publisher": "Sparrow",
"media_type": "CD"
},
{"artist": new_artist,
"title": "Love Liberty Disco",
"release_date": datetime.date(1999,11,16),
"publisher": "Sparrow",
"media_type": "CD"
},
{"artist": new_artist,
"title": "Thrive",
"release_date": datetime.date(2002,03,26),
"publisher": "Sparrow",
"media_type": "CD"}
]
Album.insert_many(albums).execute()
现在我们准备学习如何修改数据库中的记录!
使用基本查询通过 peewee 修改记录
在数据库世界中,修改记录是很常见的事情。peewee 项目使修改数据变得非常容易。下面是一些演示如何操作的代码:
# edit_data.py
import peewee
from models import Album, Artist
band = Artist.select().where(Artist.name=="Kutless").get()
print band.name
# shortcut method
band = Artist.get(Artist.name=="Kutless")
print band.name
# change band name
band.name = "Beach Boys"
band.save()
album = Album.select().join(Artist).where(
(Album.title=="Thrive") & (Artist.name == "Newsboys")
).get()
album.title = "Step Up to the Microphone"
album.save()
基本上,我们只需查询这些表,以获得我们想要修改的艺术家或专辑。前两个查询做同样的事情,但是一个比另一个短。这是因为 peewee 提供了一种快捷的查询方法。要实际更改记录,我们只需将返回对象的属性设置为其他值。在这种情况下,我们把乐队的名字从“无裤”改成了“沙滩男孩”。
最后一个查询演示了如何创建一个 SQL 连接,它允许我们在两个表之间进行匹配。如果您碰巧拥有两张同名的 CD,但您只想让查询返回与名为“Newsboys”的乐队相关联的专辑,那么这就很好了。
这些查询有点难以理解,所以您可以将它们分成更小的部分。这里有一个例子:
query = Album.select().join(Artist)
qry_filter = (Album.title=="Step Up to the Microphone") & (Artist.name == "Newsboys")
album = query.where(qry_filter).get()
这更容易跟踪和调试。您也可以对 SQLAlchemy 的查询使用类似的技巧。
如何删除 peewee 中的记录
在 peewee 中从表中删除记录只需要很少的代码。看看这个:
# del_data.py
from models import Artist
band = Artist.get(Artist.name=="MXPX")
band.delete_instance()
我们所要做的就是查询我们想要删除的记录。一旦我们有了实例,我们就调用它的 delete_instance 方法,这样就删除了记录。真的就这么简单!
包扎
peewee 项目很酷。它最大的缺点是它支持的数据库后端数量有限。然而,该项目比 SQLAlchemy 更容易使用,我认为这很神奇。peewee 项目的文档非常好,值得一读,以了解本教程中没有涉及的所有其他功能。试试看,看你怎么想!