2009-08-26 7 views
1

私は、更新したいORMマップオブジェクトを持っています。私はすべての属性を辞書で検証して保護しています(キーワード引数)。今、辞書のようにすべてのオブジェクトの属性を更新したいと思います。SA ORMオブジェクトの属性を一括割り当てする方法はありますか?

for k,v in kw.items(): 
    setattr(myobject, k, v) 

SQLAlchemyからスローされました(AttributeError Exception)。

myobject.attr1 = kw['attr1'] 
myobject.attr2 = kw['attr2'] 
myobject.attr3 = kw['attr3'] 

などは、私はそれを避けたい、恐ろしいコピーペーストコードです。#

どのように私はこれを達成することができますか? SQLAlchemyはすでにコンストラクタ(myobject = MyClass(** kw))でやりたいことと似たようなことをしていますが、そこにあるすべてのメタプログラミング難読化されたクラップスを見つけることはできません。 SAから

エラー:

<<   if self.trackparent: 
        if value is not None: 
         self.sethasparent(instance_state(value), True) 
        if previous is not value and previous is not None: 
         self.sethasparent(instance_state(previous), False) 
>> self.sethasparent(instance_state(value), True) 
AttributeError: 'unicode' object has no attribute '_sa_instance_state' 
+0

は、あなたの辞書Unicodeオブジェクト内のキーであり、あなたが実行していますPython 2.xで?もしそうなら、unicodeでsetattrを使うのはあまり幸せでないかもしれません。チェックするだけのもの。 –

答えて

3

あなたは関係属性にUnicode文字列を代入しようとしています。あなたが持っていると言う:

class ClassA(Base): 
    ... 
    b_id = Column(None, ForeignKey('b.id')) 
    b = relation(ClassB) 

そして、あなたがやろうとしている:

あなたはどちらかやるべき
my_object = ClassA() 
my_object.b = "foo" 

my_object.b_id = "foo" 
# or 
my_object.b = session.query(ClassB).get("foo") 
+0

私は気になります。それが解決策でした。 kw ['attr1'] = Session.query(MyClass).get(kw ['attr1']) – Tom

+0

私がちょうど見つけた驚くべきものは、あなたが実際にintをrelation属性に設定すると、私は自分でそれをテストしました。 id = 1のオブジェクトbが存在する場合、myobject.b = 1が動作します。関係から得られたidがintに正しくキャストされていないのに、ユニコードとして残っているため、バリデーターが壊れているようです。 Seems SAはintを好きですが、関係プロパティに割り当てられたユニコードはありません – Tom

+1

奇妙なことに、intをリレーションに割り当てると、同じエラーが発生します。 –

2
myobject.__dict__.update(**kw) 
+0

悲しいことに、SQLAlchemyではこれがうまくいきません。 __dict__は正しく更新されますが、SAはそのオブジェクトに「汚れた」フラグを立ててDBに保持しているようです。 – Tom

関連する問題