哈Ha!
最近,我的任务是用Python编写一个Python网络应用程序,以便在用餐参与者之间共享餐厅账单。由于我们需要一个数据库来存储有关订单和用户的数据,因此出现了选择ORM来处理数据库的问题。开发是在Flask上进行的,因此Django ORM被立即席卷而去,最初的选择是在SQLAlchemy的方向上。一方面,这个ORM几乎是万能的,但是由于这个原因,它很难掌握。在经历了一段时间的炼金术之后,我决定找到一个更简单的选择,以便更快地进行开发。结果,Pony ORM被选为该项目。

立即让我感到惊讶的是,将查询写到数据库的语法比炼金术中的麻烦。同样,编写程序需要更少的时间和代码行。
我决定写一篇简短的评论文章来分享我使用Pony的经验。我希望它可以帮助新手程序员快速掌握与数据库一起使用的应用程序的开发。
PonyORM的优点:
- 查询编写仅使用Python语法(生成器表达式或lambda函数)
- 自动缓存查询和对象
- 完整的组合键支持
作为主要缺点,我将强调缺乏迁移机制(开发人员正在为此而努力)
, , Pony , , .
Pony , .
pip Pony:
pip install pony
DB API :
- PostgreSQL: psycopg psycopg2cffi
- Oracle: cx_Oracle
- MySQL: PyMySQL
Pony:
from pony.orm import *
— . .
db = Database()
. Database db.bind() . . SQLite ( ) PostgreSQL (). , Database. :
settings = dict(
sqlite=dict(provider='sqlite', filename='pony.db', create_db=True),
postgres=dict(provider='postgres', user='pony', password='pony', host='localhost',
database='pony')
)
:
db = Database(**settings['postgres'])
ER . , Python . , .

:
from datetime import datetime
from pony.orm import *
db = Database()
class User(db.Entity):
id = PrimaryKey(int, auto=True)
fullname = Optional(str)
password = Optional(str)
nickname = Optional(str)
lended = Set('Credit', reverse='lender')
borrowed = Set('Credit', reverse='borrower')
credit_editions = Set('CreditEdition', reverse='user')
sessions = Set('UserInSession')
affected_editions = Set('CreditEdition', reverse='affected_user')
class Session(db.Entity):
id = PrimaryKey(int, auto=True)
title = Optional(str)
start = Optional(datetime)
end = Optional(datetime)
ordereders = Set('OrderedItem')
users = Set('UserInSession')
class OrderedItem(db.Entity):
id = PrimaryKey(int, auto=True)
session = Required(Session)
title = Optional(str)
price = Optional(int)
user_in_sessions = Set('UserInSession')
class Credit(db.Entity):
id = PrimaryKey(int, auto=True)
lender = Required(User, reverse='lended')
borrower = Required(User, reverse='borrowed')
value = Optional(int)
credit_editions = Set('CreditEdition')
class UserInSession(db.Entity):
id = PrimaryKey(int, auto=True)
user = Required(User)
session = Required(Session)
orders = Set(OrderedItem)
value = Optional(int)
class CreditEdition(db.Entity):
id = PrimaryKey(int, auto=True)
user = Required(User, reverse='credit_editions')
affected_user = Required(User, reverse='affected_editions')
credit = Required(Credit)
old_value = Optional(int)
new_value = Optional(int)
db.generate_mapping()
, , .
( ). :
session = Session[sid]
Session , id == sid.
而且,正如我上面所说,Pony中的查询可以用生成器表达式编写,这使得编写它们的方法比在炼金术中方便得多。
下面是一个示例,在该示例中,向数据库发送了一个请求,以选择属于此会话的参与者但不是虚拟用户的用户。
users = select(u for u in User if u not in session.users.user and not u.virtual)
结论
希望我的文章对某人有所帮助。如果您也对Pony感兴趣,我将在下面留下指向文档和社区电报频道的链接。
感谢您的关注!
小马电报社区文档