2011-08-30 87 views
0

好的,所以我在這裏遇到了一些問題。我需要能夠爲某些sqlalchemy創建一種導入/導出功能。現在,這些都不是我定義的對象,所以要得到我做的列:重新創建一些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作爲收到。我目前contraining誰定義這些類的人擁有所有的默認值初始化指標的影響,所以我可以只:

obj = SomeClass() 
exec "obj." + attr + " = " + param[attr] 

不過我想甚至從這個約束脫身。有什麼辦法可以做到這一點?

+1

1.爲什麼? 2.使用泡菜。 3.除非絕對必要,否則不要使用eval - 這裏getattr/setattr就足夠了。 –

+0

因爲我看不到另一種創建導入/導出對象機制的方式。鹹菜和sqlalchemy物品一起工作嗎? – Bogdan

+0

pickle有一個處理任何類型的對象的協議。 –

回答

4

對於所有可能的sqlalchemy映射類,序列化不可能是泛化的,類可能具有未存儲在數據庫中的屬性,或者必須通過relationship屬性在多個間接層級間推斷。總之,只有你知道如何序列化特定類的特定用途。


讓我們假設你只需要或正在考慮關心的特定類的特定實例的列值(以res)。這是一個粗略的函數,它將返回一個僅包含這些值的字典。

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)) 

,並從字典重新實例*

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來添加該案例,然後迭代該集合。

* 序列化中間字典和類是留作練習。