2013-01-31 43 views
18

我想使用orm复制SQLAlchemy中的模型实例(行)。我首先想到的是要做到这一点:SQLAlchemy:修改分离对象

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

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

然而,显然是分离的对象仍然是“记住”它有什么ID,即使我将ID设置为无,而这是超脱。因此,session.flush()尝试执行UPDATE,将主键更改为null。

这是预期的行为?如何删除此属性的“内存”,并将分离的对象重新添加到会话时将其视为新对象?一般来说,如何克隆SQLAlchemy模型实例?

回答

34

这种情况下可使用make_transient()辅助函数:

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

谢谢,没有看到它的文档。 –

+4

复制关系以及@zzzeek的正确方法是什么? – jmagnusson

+0

我也对类似的东西感兴趣。我有兴趣将克隆一个实体(一行)及其所有“子”实体(其他表中的行,外键指向此行),并将此新的重复行及其重复的子行附加到新的父实体通过新的重复行中的不同外键(但不影响现有实体及其子实体)。我可以在另一个问题上看到这个部分的答案,因此: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

如果你的对象是“挂起”,这doesn没有任何关系。即那么外键列尚未填充。 – gromgull

+0

它也不复制方法和混合属性。 – Jakobovski