12

autoload を使用して既存のデータベースを使用したいと考えています。宣言構文 (model/_init _.py )なしでそれを行う方法を知っています。

def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    t_events = Table('events', Base.metadata, schema='events', autoload=True, autoload_with=engine)
    orm.mapper(Event, t_events)

    Session.configure(bind=engine)  

class Event(object):
    pass

これは問題なく動作しますが、宣言構文を使用したいと思います。

class Event(Base):
    __tablename__ = 'events'
    __table_args__ = {'schema': 'events', 'autoload': True}

残念ながら、この方法で次のようになります。

sqlalchemy.exc.UnboundExecutionError: このテーブルのメタデータにバインドされているエンジンはありません。autoload_with=<someengine> を介してエンジンをテーブルに渡すか、metadata.bind=<someengine> を介して MetaData をエンジンに関連付けます。

ここでの問題は、モデルをインポートする段階でエンジンをどこから取得するか (autoload_with で使用するため) がわからないことです (init_model() で利用可能です)。追加してみました

meta.Base.metadata.bind(engine)

environment.py に追加しましたが、機能しません。エレガントな解決策を見つけた人はいますか?

4

4 に答える 4

12

わかりました、私はそれを理解したと思います。解決策は、モデル オブジェクトを の外部で宣言することmodel/__init__.pyです。モジュール (この場合は)__init__.pyから何かをインポートするときに が最初のファイルとしてインポートされると結論付けました。modelinit_model()

これを避けるために、modelモジュールに新しいファイルを作成しましたobjects.pyEvent次に、このファイルですべてのモデル オブジェクト ( など) を宣言しました。

次に、次のようにモデルをインポートできます。

from PRJ.model.objects import Event

autoload-withさらに、テーブルごとの指定を避けるために、次の行を の最後に追加しましたinit_model()

Base.metadata.bind = engine

このようにして、次のように定型コードなしでモデル オブジェクトを宣言できます。

class Event(Base):
    __tablename__ = 'events'
    __table_args__ = {'schema': 'events', 'autoload': True}

    event_identifiers = relationship(EventIdentifier)

    def __repr__(self):
        return "<Event(%s)>" % self.id
于 2010-12-29T16:51:55.340 に答える
0

関数内でメタデータをエンジンにバインドする方法については、Pylons で SQLAlchemy を使用するチュートリアルを参照してくださいinit_model

ステートメントがモデル メタデータをエンジンに正常にバインドする場合、独自の関数meta.Base.metadata.bind(engine)でこの初期化を実行できるはずです。init_modelこの関数でメタデータ バインディングをスキップするつもりはなかったと思います。

于 2010-12-28T04:19:00.483 に答える