- 此问题在此处已有答案**:
Avoiding boilerplate session handling code in sqlalchemy functions(4个答案)
How to manage this commit/rollback pattern in sqlalchemy(2个答案)
三年前关闭了。
嗨,对不起,这是一个非常开放式的问题,更像是一个编码建议。寻找什么是使用sqlalchemy会话的 flask 项目的最佳实践。找不到一个博客,可以回答我的问题,因此在这里问它。
我有一个 flask 应用程序的项目结构类似如下:
---services
--- service_1.py
--- service_2.py
---models.py
---adapter.py
---app.py
所有的业务逻辑都驻留在服务中,服务中的方法调用适配器中的方法与数据库进行交互。
适配器是数据访问层,所有的sql查询都在里面发生。适配器代码如下:
from .models import *
class DBAdapter(object):
def __init__(self, session):
self._db_session = get_session() # get a sql alchemy session
def create_customer(**kwargs):
c = Customer(**kwargs)
self._db_session.add(c)
return c
.
.
.
def commit(self):
self.session.commit()
def close_session(self):
self.session.close()
该服务看起来像这样:
from ..adapter import DBAdapter
class Service1(object):
def __init__(self, a):
self.a = a
self._db_adapter = DBAdapter()
def do_something(self, x, y):
if x != 10:
self.create_something(x)
self._db_adapter.commit()
self._db_adapter.close_session()
return
self._db_adapter.create_customer(y)
self._db_adapter.create_something_else(x)
self._db_adapter.commit()
self._db_adapter.close_session()
return
现在的问题是如何在每个return语句之前不重复self._db_adapter.close_session()
的情况下关闭会话,需要在return之前在if条件中关闭两次,然后在结束时关闭。
我是否应该以不同的方式创建数据访问层DBAdapter
?
我想保持会话干净,只在服务初始化时创建它,所以我不能像这样把它放在flask的g对象中:
Flask and sqlalchemy: handling sessions
2条答案
按热度按时间8qgya5xd1#
Python有上下文管理器来处理类似的事情,请考虑以下内容:
现在,您可以自动关闭会话:
或者您可以考虑使用even more convenient pattern,它可以为您执行提交/回滚。
qzwqbdag2#
让会话/事务充当上下文管理器,并从自定义/客户端程序封装其行为: