首页 > 解决方案 > 在 sqlalchemy 中使用会话范围之外的对象

问题描述

我有一个在某些 API 调用开始时创建的 Job 对象:

class Job(Base):
    __tablename__ = 'jobs'
    id = Column(BIGINT, primary_key=True)
    end_date = Column('end_date', DateTime(timezone=True), nullable=False)
    start_date = Column('start_date', DateTime(timezone=True), default=datetime.datetime.utcnow(), nullable=False)
    name = Column('name', TEXT, nullable=False)

    def __init__(self, name):
        self.name = name
        self.start_date = datetime.datetime.utcnow()
        self.end_date = 'infinity'

当调用 api 时,我正在创建一个新工作:

job=Job(name="job1")
session.add(job)
session.commit()
session.close()

但是,在作业开始后,我想将此作业对象作为参数发送到其他一些流程,以便了解哪个作业负责该流程。

问题是我关闭会话后无法使用 python 对象作业,我会收到以下错误:

sqlalchemy.orm.exc.DetachedInstanceError: Instance <Job at 0x3c67f30> is not bound to a Session; attribute refresh operation cannot proceed (Background on this error at: http://sqlalche.me/e/bhk3)

我想在作业对象开始之前保存它。无论如何,我可以在会话范围之外使用它,但是在我保存之后?我知道以后可以查询它,但我不想,我想使用我创建的同一个作业对象。

我目前的解决方案:

session.add(job)
session.commit()
get_job_id_query = (
session.query
.find(Job.id).filter(Job.end_date == 'infinity')
.filter(Job.name == job.name)
)
job_id = get_job_id_query.all()[0][0]
session.close()

然后我将 id 传递给下一个流程。

标签: pythondatabasesqlalchemy

解决方案


Session 采用expire_on_commit参数,如果设置为 ,则在提交后将保持对象可访问False

使用它时,您需要注意,如果数据由另一个会话更新,“过期”对象将与数据库不同步。


推荐阅读