好的,所以我在这里遇到了一些问题。我需要能够为某些sqlalchemy创建一种导入/导出功能。现在这些不是我正在定义的对象,所以要获取我正在做的列:
for attr, value in res.__class__.__dict__.iteritems():
if isinstance(value, InstrumentedAttribute):
data = eval("res." + str(attr))
param_dict[attr] = data
现在这正确地获取了该对象的属性。但是,我可以确定 init 的参数是相同的,因为我不是处理这个对象的人。所以可能会出现这样的情况:
class SomeClass(model.Base):
my_column = Column(String)
....some other stuff...
def __init__(self, mycolumn, ...):
self.my_column = mycolumn
因此,在这种情况下,字段名称和init收到的参数名称之间没有任何对应关系。我目前正在限制那些定义这些类的人,以使所有init参数都具有默认值,所以我可以:
obj = SomeClass()
exec "obj." + attr + " = " + param[attr]
但是我想摆脱这种限制。有什么办法可以实现吗?
答案 0 :(得分:4)
序列化不能真正推广到所有可能的sqlalchemy映射类,类可能具有未存储在数据库中的属性,或者必须通过relationship
属性跨多个间接层推断。简而言之,只有你知道如何为特定用途序列化特定类。
让我们假装您只需要或关心所考虑的特定类的特定实例的列值(在res
中)。这是一个粗略函数,它将返回仅包含这些值的dict。
from sqlalchemy.orm.attributes import manager_of_class
from sqlalchemy.orm.properties import ColumnProperty
def get_state_dict(instance):
cls = type(instance)
mgr = manager_of_class(cls)
return dict((key, getattr(instance, key))
for key, attr in mgr.iteritems()
if isinstance(attr.property, ColumnProperty))
并从dict *
重新创建一个实例def create_from_state_dict(cls, state_dict):
mgr = manager_of_class(cls)
instance = mgr.new_instance()
for key, value in state_dict.iteritems():
setattr(instance, key, value)
return instance
如果你需要更复杂的东西,可能是处理未显示为列的关系(如多对多关系),你可以通过查找sqlalchemy.orm.properties.RelationshipProperty
来添加该案例,然后迭代集合
* 序列化中间词典和类作为练习。