python - SQLAlchemy:将当前 session 包装到模型中的正确方法?

标签 python sqlalchemy

在使用 SQLalchemy 构建模型时,我正在使用 declarative_base... 所以我有一个看起来像这样的模型:

from sqlalchemy.orm import sessionmaker, scoped_session                             
engine = create_engine("mysql...")
session_factory = sessionmaker(bind=engine)                                         
SessionHeap = scoped_session(session_factory)          
Base = declarative_base()

class MyTable(Base, Actions):                                                      
    __tablename__ = 'mytable'                                                     
    id = Column(Integer, primary_key=True)                                       
    date = Column(Integer)                                                                                                      
    tag = Column(String(50))

class Actions(object):                                                              
    @classmethod                                                                    
    def create(cls, **kwargs):                                                      
        session = SessionHeap()                                                     
        session.add(cls(**kwargs))                                                  
        session.commit()                                                            
        session.close()                                                             
        SessionHeap.remove()                                                        

    def update(self, **kwargs):                                                     
        for key, val in kwargs.iteritems():                                         
            self.__setattr__(key, val)                                              
        session = inspect(self).session                                             
        session.commit()                                                            

    @classmethod                                                                    
    def _search(cls, **kwargs):                                                     
        session = SessionHeap()                                                     
        query = session.query(cls).filter_by(**kwargs)                              
        session.commit()                                                            
        session.close()                                                             
        SessionHeap.remove()                                                        
        return query         

我不确定什么时候应该调用 session.close() 甚至什么时候删除 session ,我一直遇到麻烦,尤其是在查询时,某些 session 不会关闭并且数据库会挂起。什么是更好的模式? (请注意,我想将所有方法都包装在模型本身中,而不是在其他一些全局命名空间中)

最佳答案

简短回答:它是特定于应用程序的。

如果您正在实现长时间运行的进程(如后端守护进程),您可能需要在每个 session 生命周期内执行多次提交。如果您正在开发 HTTP 应用程序,则模式通常是每个 HTTP 请求一次提交(在最后,在连接断开时)。大多数现代 Web 框架都提供请求设置/拆卸的 Hook 。例如,在 Flask 中,您可以将 session.commit()/session.close() 放在用 @app.teardown_request 装饰的方法下。

我推荐以下方法:

  • (来自 SQLAlchemy 文档)作为一般规则,将 session 的生命周期与访问和/或操作数据库数据的函数和对象分开并置于外部。这将极大地有助于实现可预测且一致的交易范围。
  • 用 session.flush() 语句替换上面的 session.commit() 语句。 flush() 将在不提交事务的情况下保留数据。删除 session.close() 语句。请记住,session.close() 会将连接返回给引擎/连接池,它实际上并没有关闭连接。
  • 实现您的自定义 DBRollbackException() 异常,使用它在出现任何错误时回滚当前事务。
  • 在最后提交一次(例如,根据要求拆卸)

关于python - SQLAlchemy:将当前 session 包装到模型中的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34560607/

相关文章:

postgresql - "Can' t adapt type"错误关于 SQLAlchemy/PostGreSQL 的外键属性

python - Pickle序列化顺序之谜

python - Paramiko Authentication验证(原来是Python异常处理)

python - 如何在另一个应用程序开始运行的同时执行 python 脚本?

postgresql - 无法使用 docker compose 通过 postgresql 启动 FastAPI 服务器

python - SQLAlchemy 可以与 Google Cloud SQL 一起使用吗?

python - 通过 XML 解析时保留 CDATA 部分

python - python package namespaces : z3c, zc, collective 背后是什么?

python - 使用 psycopg2 模块将值插入数据库时​​出错

python - 是否可以将 namedtuple 与 SQLalchemy 一起使用?