2013-01-31 23 views
18

Chcę zduplikować egzemplarz modelu (wiersz) w SQLAlchemy za pomocą narzędzia orm. Moją pierwszą myślą było, aby to zrobić:SQLAlchemy: Modyfikacja odłączonego obiektu

i = session.query(Model) 
session.expunge(i) 

old_id = i.id 
i.id = None 
session.add(i) 
session.flush() 
print i.id #New ID 

Jednak najwyraźniej wolnostojący obiekt nadal „pamięta”, co id miał, chociaż ustawić identyfikator Żaden natomiast został oderwany. W ten sposób session.flush() próbuje wykonać UPDATE, zmieniając klucz podstawowy na wartość null.

Czy to oczekiwane zachowanie? Jak mogę usunąć "pamięć" tego atrybutu i traktować odłączony obiekt jako nowy obiekt po ponownym dodaniu go do sesji? Jak ogólnie można sklonować instancję modelu SQLAlchemy?

Odpowiedz

34

sprawa ta jest dostępna za pomocą funkcji make_transient() pomocnika:

inst = session.query(Model).first() 
session.expunge(inst) 

make_transient(inst) 
inst.id = None 
session.add(inst) 
session.flush() 
print inst.id #New ID 
+0

Dzięki, nie widział go w docs. –

+4

Jaki jest właściwy sposób kopiowania relacji, @zzzeek? – jmagnusson

+0

Ja też jestem zainteresowany czymś podobnym. Interesuje mnie klonowanie encji (wiersza) wraz ze wszystkimi jej elementami podrzędnymi (wiersze w innych tabelach, z kluczami obcymi wskazującymi w tym wierszu) i dołączanie tego nowego duplikatu wiersza i jego duplikatów do nowej jednostki nadrzędnej za pomocą innego klucza obcego w nowym zduplikowanym wierszu (ale bez wpływu na istniejącą jednostkę i jej elementy podrzędne). Widzę tę częściową odpowiedź na inne pytanie na SO: http://stackoverflow.com/questions/20112850/sqlalchemy-clone-table-row-with-relations?lq=1 – Soferio

1
def duplicate(self): 
    arguments = dict() 
    for name, column in self.__mapper__.columns.items(): 
     if not (column.primary_key or column.unique): 
      arguments[name] = getattr(self, name) 
    return self.__class__(**arguments) 
+0

Jeśli twój obiekt jest "oczekujący", to robi nie ma żadnych związków. To znaczy. Kolumny klucza obcego nie są wtedy jeszcze wypełnione. – gromgull

+0

Nie kopiuje również metod i atrybutów hybrydowych. – Jakobovski