gpt4 book ai didi

python - 在 sqlalchemy 函数中避免样板 session 处理代码

转载 作者:IT老高 更新时间:2023-10-28 21:09:32 27 4
gpt4 key购买 nike

我有一个使用 sqlalchemy 的具有许多小型数据库访问功能的 python 应用程序。我试图避免围绕这些函数使用大量样板 session 处理代码。

我有很多看起来像这样的函数:

def get_ticket_history(Session, ticket_id):
s = Session()
try:
rows = s.query(TicketHistory)\
.filter(TicketHistory.ticket_fk==ticket_id)\
.order_by(TicketHistory.id.desc()).all()
s.commit()
return rows
except:
s.rollback()
raise
finally:
s.close()

我正在尝试重构这些功能,但不确定我是否有最好的方法。我目前拥有的最好的如下:

def execute(Session, fn, *args, **kwargs):
s = Session()
try:
ret = fn(s, *args, **kwargs)
s.commit()
return ret
except:
s.rollback()
raise
finally:
s.close()

def get_ticket_history(self, ticket_id):
def sql_fn(s):
return s.query(TicketHistory)\
.filter(TicketHistory.ticket_fk==ticket_id)\
.order_by(TicketHistory.id.desc()).all()
return execute(self.sentinel_session, sql_fn)

有没有更好或更惯用的方法来做到这一点?也许使用装饰器?

谢谢,乔恩

最佳答案

SQLAlchemy 文档提供了一种使用上下文管理器执行此操作的可能方法。

http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#when-do-i-construct-a-session-when-do-i-commit-it-and-when-do-i-close-it

为了完整起见,这里复制代码片段:

from contextlib import contextmanager

@contextmanager
def session_scope():
"""Provide a transactional scope around a series of operations."""
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()

这个 session_scope 现在可以干净利落地使用,无需重复样板。

class ThingOne(object):
def go(self, session):
session.query(FooBar).update({"x": 5})

class ThingTwo(object):
def go(self, session):
session.query(Widget).update({"q": 18})

def run_my_program():
with session_scope() as session:
ThingOne().go(session)
ThingTwo().go(session)

关于python - 在 sqlalchemy 函数中避免样板 session 处理代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14799189/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com