Using objects outside of the session`s scope in sqlalchemy
Question:
I have an Job object that I create in the beginning of some API call:
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'
When the api is called I’m creating a new job :
job=Job(name="job1")
session.add(job)
session.commit()
session.close()
However, after the job starts I want to send this job object as a parameter to some other flows in order to know which job was responsible for that flow.
The problem is that after I closed the session I can’t use the Python object job, I will get the following error :
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)
I want to save the job object before it starts. Anyway, can I use it outside of the session’s scope, but after I saved it? I know that I can query it afterwards, but I don’t want to, I want to work with the same job object I created.
My current solution :
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()
and then I pass the id to the next flows.
Answers:
Session takes an expire_on_commit argument that will leave objects accessible after being committed if it is set to False
.
When using it, you need to be aware that “expired” objects will be out of sync with the database if the data is updated by anothe session.
I have an Job object that I create in the beginning of some API call:
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'
When the api is called I’m creating a new job :
job=Job(name="job1")
session.add(job)
session.commit()
session.close()
However, after the job starts I want to send this job object as a parameter to some other flows in order to know which job was responsible for that flow.
The problem is that after I closed the session I can’t use the Python object job, I will get the following error :
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)
I want to save the job object before it starts. Anyway, can I use it outside of the session’s scope, but after I saved it? I know that I can query it afterwards, but I don’t want to, I want to work with the same job object I created.
My current solution :
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()
and then I pass the id to the next flows.
Session takes an expire_on_commit argument that will leave objects accessible after being committed if it is set to False
.
When using it, you need to be aware that “expired” objects will be out of sync with the database if the data is updated by anothe session.