How to use make_transient () to duplicate a displayed SQLAlchemy object?

I know that the question of how to duplicate or copy the associated SQLAlchemy object has been asked many times. The answer always depends on the needs and how the “duplicate” or “copy” is interpreted. This is a specialized version of the question because I got a hint for using make_transient() for this.

But I have some problems with this. I do not know how to handle the primary key (PK) here. In my cases of using a PC, SQLA (or a database in the background) is always automatically generated. But this does not happen with a new duplicate object.

The code is a bit 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() 
+6
source share
1 answer
 if __name__ == '__main__': obj = GetOneMachineDataFromDatabase() make_transient(obj) obj._oid = None _session.add(obj) # this include a flush() and create a new primary key _session.commit() 
+4
source

Source: https://habr.com/ru/post/987369/


All Articles