因此,我在模型中声明了一个克隆方法,如下所示:
def clone(self):
valid_cols = [key for key, val in vars(type(self)).items() if isinstance(val, InstrumentedAttribute) and key not in self.__table__.primary_key.columns]
return type(self)(**{key: getattr(self, key) for key in valid_cols})
这使得克隆记录并更新其属性变得非常方便
不过有个问题。每当我更新一个已经复制了关联关系的字段时,就会出现不希望出现的行为
例如,以:
class Parent(Base):
__tablename__ = "parent"
id = Column(Integer, primary_key=True)
class Child(Base):
__tablename__ = "child"
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey(Parent.id))
parent = relationship(Parent, backref=Backref("children", uselist=True, cascade="all"))
def clone(self):
from sqlalchemy.orm.attributes import InstrumentedAttribute
valid_cols = [key for key, val in vars(type(self)).items() if isinstance(val, InstrumentedAttribute) and key not in self.__table__.primary_key.columns]
return type(self)(**{key: getattr(self, key) for key in valid_cols})
metadata.create_all()
parent1 = Parent()
parent2 = Parent()
child1 = Child(parent=parent1)
s.add_all([parent1, parent2, child1])
s.commit()
child2 = child1.clone()
child2.parent_id = parent2.id
child2.parent_id # 2
s.add(child2)
s.commit()
child2.parent_id # 1
child2.parent is parent1 # True
因此,很明显,child2的父母应该是parent2,而不是parent1。但是,在克隆方法期间,parent1直接设置在child2的“Child.parent”关系上,因此即使child2的“Child.parent\u id”列后来设置为parent2的id,orm也不在乎,并在提交时放弃该更新
我的问题是,当关系属性和列属性之间存在分歧时,有没有办法让orm将最后修改的属性作为绝对真理
我可以避免在clone方法中设置关系属性,但我不想这样做,因为在更复杂的情况下,访问旧对象的关系非常有用,而且我发现在我的用例中,能够直接设置列属性而不是设置它们的关系属性也很重要
在将任何内容提交到数据库之前,我还希望对克隆对象执行任何必需的更新
基本上,有没有简单的银弹?我是否可以修改clone方法,使其他所有内容保持不变,在示例代码的末尾,child2的父对象将是parent2而不是parent1
非常感谢
目前没有回答
相关问题 更多 >
编程相关推荐