2011-11-09 10 views
0

私はPythonを学ぶのに楽しい時間を過ごしていますが、私はちょうどSQLAlchemyに再帰関数を組み込もうとしています。SQLAlchemy再帰

基本的には、データベースに入れるクラスのインスタンスを作成する関数を持っています。この関数の中で、インスタンスに親クラスがあるかどうか(自己参照隣接テーブルを使って定義されているかどうか)をユーザーに入力します。そうであれば、関数は再帰的に呼び出されます。この関数は、親クラスが必要ない場合に機能すると思われますが、再帰要素がアクティブになるたびにクラッシュします。

私のコードはそうのようなものです:

engine = create_engine('sqlite:///recDB.db') 
Session = sessionmaker(bind=engine) 
session = Session() 
Base = declarative_base() 

class IngList(Base): 
    __tablename__ = "ingList" 

    id = Column(Integer, primary_key = True) 
    ingredient = Column(String, nullable=False) 
    parentIng = Column(Integer, ForeignKey('ingList.id')) 
    children = relationship("IngList",backref=backref('parent', remote_side=[id])) 

    def __init__(self, ingredient): 
     self.ingredient = ingredient 

def addIngredient(ingredient): 
    global newIngList 
    newIng = IngList(ingName) #create new class instance 
    parentIng = raw_input("To add parent ingredient, type it. Otherwise press enter") 
    if parentIng != '': 
     parentIngObj = addIngredient(parentIng) # Recursion! 
     newIng.parentIng = parentIngObj 
    newIngList.append(newIng) 

if __name__ == '__main__': 
    newIngList = [] 
    ingredient = raw_input("Enter new ingredient") 
    addIngredient(ingredient) 
    for ing in newIngList 
     session.add(ing) 
    session.commit() 

私は読み、それを維持するために、このサンプルをシンプルに保ち、私はいくつかの重要な情報が欠けている場合は、私に知らせてくださいました。

私は再帰的にクラスインスタンスがスコープを失っていると仮定しましたが、グローバル変数をリスト変数に追加してもそれを修正していないようです。また、セッションがバッファのような役割を果たすという事実は、スコープの問題を処理するとも考えました。

eager loadingとは関係がありますか?私はドキュメンテーションでそれを見ましたが、実際にそれを理解していません。

私は取得していますエラーは次のとおりです。

Traceback (most recent call last): 
    File "C:\workspace\recipes\langProc.py", line 102, in <module> 
    session.commit() 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 645, in commit 
    self.transaction.commit() 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 313, in commit 
    self._prepare_impl() 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 297, in _prepare_impl 
    self.session.flush() 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 1547, in flush 
    self._flush(objects) 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\session.py", line 1616, in _flush 
    flush_context.execute() 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 328, in execute 
    rec.execute(self) 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 472, in execute 
    uow 
    File "c:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 2153, in _save_obj 
    execute(statement, params) 
    File "c:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1399, in execute 
    params) 
    File "c:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1532, in _execute_clauseelement 
    compiled_sql, distilled_params 
    File "c:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1640, in _execute_context 
    context) 
    File "c:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1633, in _execute_context 
    context) 
    File "c:\Python27\lib\site-packages\sqlalchemy\engine\default.py", line 330, in do_execute 
    cursor.execute(statement, parameters) 
sqlalchemy.exc.InterfaceError: (InterfaceError) Error binding parameter 0 
- probably unsupported type. 
u'UPDATE "ingList" SET "parentIng"=? WHERE "ingList".id = ?' 
(<assignDB.IngList object at 0x00000000096969E8>, 4) 
+0

は確かに参考になります。 – Xion

+0

私が家に帰るとします。私は仕事中に私のプロジェクトを持っていません。 – abroekhof

+0

セッションのスコープが何であるかは不明です。それは問題を理解するために不可欠かもしれません。実際のコードを最小限に抑え、実行されていることを確認してから投稿する方が良いと思います。 – wberry

答えて

3

私はあなたがバグ/あなたのコードが動作しない作るタイプミスのカップルを持っていると思います。私は、あなたが問題を示すために、小さなコードサンプルを作成したと仮定し、私はあなたが元のコードでそれらを修正したら、あなたは問題が同様に解決されることを願っています:

  • 代わりnewIng.parentIng = parentIngObjのあなたはnewIng.parent = parentIngObjを持っている必要があります。私はこれが問題を解決すべきだと思う。
    親インスタンスは、キーではなくリレーションシップオブジェクトに割り当てる必要があります。
    • タイプミス:ingredientがあるべきパラメータJFセバスチャンの提案を使用して、オブジェクトが既にデータベースに格納されていた場合には、あまりにも仕事ができるが、新しいインスタンスはidはまだ
    • addIngredient(...)
    • が割り当てられていないことは二つの問題があります ingNameに、またはその逆に
    • に変更されました。addIngredient(...)は値を返しません。実際にはNoneparentの関係に割り当てます。
      また、これは単なるサンプルコードであるため、実際のコードではこれらの問題が発生していない可能性があります。あなたが得る例外のメッセージとトレースバックを取り付け
0
newIng.parentIng = parentIngObj.id 
+0

テーブルは自己参照型なので、この構造体ですか?以前はコード内の構造を使って関係を割り当てていたので、うまくいくように見えました。答えをありがとう - 私は家に帰るときに私はそれをショットを与えるでしょう。 – abroekhof