我正在尝试自动构建SA映射的浅表副本 对象..目前我的功能只是:
newobj = src.__class__()
for prop in class_mapper(src.__class__).iterate_properties:
setattr(newobj, prop.key, getattr(src, prop.key))
但我在懒惰的关系中遇到麻烦......显然是getattr 触发延迟加载,但因为我不需要他们的值正确 离开,我只想复制“这应该是懒惰的” - 状态 属性......这可能吗?
编辑:我需要这个用于“数据记录”系统。也就是说,每当有人更新持久化实体时,我必须生成一个新记录,然后标记旧记录。
为了做到这一点,我创建了一个实体的浅表副本(因此SQLA发出INSERT而不是UPDATE)并从那里开始工作。
系统工作得非常好(它已经在生产中使用了几个月),但现在我想要增强它,以便它不需要所有的关系首先得到延迟加载..
答案 0 :(得分:6)
您需要的是仅复制列属性,可以使用isinstance(prop, sqlalchemy.orm.ColumnProperty)
轻松过滤。请注意,您必须复制外部存储的关系(所有多对多),因为主表中没有与它们对应的列。没有延迟加载的高级接口无法做到这一点,所以我更愿意接受这种权衡。可以使用isinstance(prop, RelationProperty) and prop.secondary
测试确定多对多关系。生成的代码如下所示:
from sqlalchemy.orm import object_mapper, ColumnProperty, RelationProperty
newobj = type(src)()
for prop in object_mapper(src).iterate_properties:
if (isinstance(prop, ColumnProperty) or
isinstance(prop, RelationProperty) and prop.secondary):
setattr(newobj, prop.key, getattr(src, prop.key))
另请注意,SQLAlchemy旨在维护为每个标识加载的单个对象,而当复制身份(主键)属性时,您的副本会破坏它,但如果您使用new(版本化)存储,则可能不是这种情况)标识符。