如何使用 make_transient() 复制 SQLAlchemy 映射对象?
How to use make_transient() to duplicate an SQLAlchemy mapped object?
我知道很多人问过如何复制或复制 SQLAlchemy 映射对象这个问题。答案始终取决于需求或如何解释 "duplicate" 或 "copy"。
这是问题的专门版本,因为我得到了使用 make_transient()
的提示。
但我对此有一些疑问。我真的不知道如何在这里处理主键(PK)。在我的用例中,PK 始终由 SQLA(或后台的数据库)自动生成。但这不会发生在新的复制对象上。
代码有点伪。
import sqlalchemy as sa
from sqlalchemy.orm.session import make_transient
_engine = sa.create_engine('postgres://...')
_session = sao.sessionmaker(bind=_engine)()
class MachineData(_Base):
__tablename__ = 'Machine'
_oid = sa.Column('oid', sa.Integer, primary_key=True)
class TUnitData(_Base):
__tablename__ = 'TUnit'
_oid = sa.Column('oid', sa.Integer, primary_key=True)
_machine_fk = sa.Column('machine', sa.Integer, sa.ForeignKey('Machine.oid'))
_machine = sao.relationship("MachineData")
def __str__(self):
return '{}.{}: oid={}(hasIdentity={}) machine={}(fk={})' \
.format(type(self), id(self),
self._oid, has_identity(self),
self._machine, self._machine_fk)
if __name__ == '__main__':
# any query resulting in one persistent object
obj = GetOneMachineDataFromDatabase()
# there is a valid 'oid', has_identity == True
print(obj)
# should i call expunge() first?
# remove the association with any session
# and remove its “identity key”
make_transient(obj)
# 'oid' is still there but has_identity == False
print(obj)
# THIS causes an error because the 'oid' still exsits
# and is not new auto-generated (what should happen in my
# understandings)
_session.add(obj)
_session.commit()
创建一个对象实例后瞬态你必须删除它的对象ID。如果没有对象 ID,您可以将它再次添加到数据库中,数据库将为它生成一个新的对象 ID。
if __name__ == '__main__':
# the persistent object with an identiy in the database
obj = GetOneMachineDataFromDatabase()
# make it transient
make_transient(obj)
# remove the identiy / object-id
obj._oid = None
# adding the object again generates a new identiy / object-id
_session.add(obj)
# this include a flush() and create a new primary key
_session.commit()
我知道很多人问过如何复制或复制 SQLAlchemy 映射对象这个问题。答案始终取决于需求或如何解释 "duplicate" 或 "copy"。
这是问题的专门版本,因为我得到了使用 make_transient()
的提示。
但我对此有一些疑问。我真的不知道如何在这里处理主键(PK)。在我的用例中,PK 始终由 SQLA(或后台的数据库)自动生成。但这不会发生在新的复制对象上。
代码有点伪。
import sqlalchemy as sa
from sqlalchemy.orm.session import make_transient
_engine = sa.create_engine('postgres://...')
_session = sao.sessionmaker(bind=_engine)()
class MachineData(_Base):
__tablename__ = 'Machine'
_oid = sa.Column('oid', sa.Integer, primary_key=True)
class TUnitData(_Base):
__tablename__ = 'TUnit'
_oid = sa.Column('oid', sa.Integer, primary_key=True)
_machine_fk = sa.Column('machine', sa.Integer, sa.ForeignKey('Machine.oid'))
_machine = sao.relationship("MachineData")
def __str__(self):
return '{}.{}: oid={}(hasIdentity={}) machine={}(fk={})' \
.format(type(self), id(self),
self._oid, has_identity(self),
self._machine, self._machine_fk)
if __name__ == '__main__':
# any query resulting in one persistent object
obj = GetOneMachineDataFromDatabase()
# there is a valid 'oid', has_identity == True
print(obj)
# should i call expunge() first?
# remove the association with any session
# and remove its “identity key”
make_transient(obj)
# 'oid' is still there but has_identity == False
print(obj)
# THIS causes an error because the 'oid' still exsits
# and is not new auto-generated (what should happen in my
# understandings)
_session.add(obj)
_session.commit()
创建一个对象实例后瞬态你必须删除它的对象ID。如果没有对象 ID,您可以将它再次添加到数据库中,数据库将为它生成一个新的对象 ID。
if __name__ == '__main__':
# the persistent object with an identiy in the database
obj = GetOneMachineDataFromDatabase()
# make it transient
make_transient(obj)
# remove the identiy / object-id
obj._oid = None
# adding the object again generates a new identiy / object-id
_session.add(obj)
# this include a flush() and create a new primary key
_session.commit()