2015-05-17 17 views
6

Tôi biết câu hỏi cách sao chép hoặc sao chép đối tượng ánh xạ SQLAlchemy đã được hỏi rất nhiều lần. Câu trả lời luôn phụ thuộc vào nhu cầu hoặc cách "sao chép" hoặc "sao chép" được diễn giải. Đây là phiên bản chuyên biệt của câu hỏi vì tôi có mẹo sử dụng make_transient() cho điều đó.Làm thế nào để sử dụng make_transient() để nhân bản một đối tượng ánh xạ SQLAlchemy?

Nhưng tôi có một số vấn đề với điều đó. Tôi không thực sự biết cách xử lý khóa chính (PK) ở đây. Trong trường hợp sử dụng của tôi, PK luôn được tự động phát hiện bởi SQLA (hoặc DB trong nền). Nhưng điều này không xảy ra với một đối tượng trùng lặp mới.

Mã này có một chút giả.

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() 
+0

Không ai có ý tưởng? – buhtz

Trả lời

4
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() 
Các vấn đề liên quan