Conosco molte volte la domanda su come duplicare o copiare un oggetto mappato SQLAlchemy. La risposta dipende sempre dalle esigenze o da come "duplicato" o "copia" viene interpretato. Questa è una versione specializzata della domanda perché ho avuto il suggerimento di usare make_transient()
per quello.Come utilizzare make_transient() per duplicare un oggetto mappato SQLAlchemy?
Ma ho qualche problema. Non so davvero come gestire la chiave primaria (PK) qui. Nei miei casi d'uso il PK è sempre generato automaticamente da SQLA (o dal DB in background). Ma questo non succede con un nuovo oggetto duplicato.
Il codice è un po 'pseudo.
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()
Nessuno ha un'idea? – buhtz