2011-04-25 30 views
5

私はFlaskアプリの一部を持っていて、複数の異なるプロジェクトで使いたいと思っています。 Flask-SQLAlchemyを使用したSQLAlchemyモデル、ビューおよびテンプレートを備えています。モジュールを使用してapp.routeデコレータを取得できますが、どのようにSQLAlchemy dbオブジェクトを処理できますか?Flask-SQLAlchemyで再利用可能なコンポーネントを作成するにはどうすればよいですか?

私のコンポーネントは別にする必要があるので、dbオブジェクトをインポートするだけではありません。しかし、私はdbオブジェクトを2回作成する必要はないと思います。メタデータと他のプロジェクトのメタデータをどのように混ぜるのですか?

答えて

3

まず、metadataを共有し、フラスコ - sqlalchemy db.Modelを再利用可能なアプリケーションのベースとして使用しないでください。

2番目には、信号、ショートカットなどをサポートするために、flask-sqlalchemyから新しいベースを拡張してすべてのクラスを再作成する必要があります。

塩基を統合し(それがあってもよいバギー):

def integrate_models(cls, nbase): 
     new_bases = list(cls.__bases__) + [nbase] 
     new_dict = dict(cls.__dict__) 
     new_dict.update(dict(nbase.__dict__)) 
     return type.__new__(cls.__class__, cls.__name__, tuple(new_bases), new_dict) 
SQLAlchemyの拡張子を持つ

例フラスコアプリ:

# -*- coding: utf-8 -*- 
from flask import Flask 
from flaskext.sqlalchemy import SQLAlchemy 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 
db = SQLAlchemy(app) 

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String(80), unique=True) 
    email = db.Column(db.String(120), unique=True) 

    def __init__(self, username, email): 
     self.username = username 
     self.email = email 

    def __repr__(self): 
     return '<User %r>' % self.username 

if __name__ == '__main__': 
     from some_model_base import init_metadata 
     init_metadata(db.Model.metadata) 

     from some_model import SomeClass 

     SomeClass = integrate_models(SomeClass, db.Model) 

     db.create_all() 

     print SomeClass.query.all() 

some_model_base.py:

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

def init_metadata(metadata): 
    Base.metadata = metadata 

そしてsome_model.py :

from sqlalchemy import Column, Integer, String 
from some_model_base import Base 

class SomeClass(Base): 
    __tablename__ = 'some_table' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(50)) 

この例では、db.create_allおよびSomeClass.queryショートカットのみをテストしました。

私の貧しい人々のために申し訳ありません。

+0

私はこれを試してみる必要があります。メインプログラムのモデルとの関係を持つように他のモジュールのモデルを構成する方法を見つけることができますか? –

+0

私は、あなたの再利用可能なアプリケーションベースクラスまたはMixInsで宣言し、それらをサブクラス化する具体的なモデルを構築するのが最善の方法だと思います。 – estin

1

flask.current_appを使用する必要があります。これは、現在のアプリケーションにアクセスするためのプロキシオブジェクトであり、一部の拡張機能で使用されているものです。

from flask import current_app 
from flaskext.sqlalchemy import SQLAlchemy 

db = SQLAlchemy(current_app) 

を、あなたが通常行うように、あなたのdbオブジェクトを使用しますので、あなたのコードは次のようになります。しかし、ユーザーがあなたのモジュールを使用していて、flaskext.sqlalchemyを使用する必要がある場合、これがうまくいくかどうかは分かりません。おそらく競合します。これをテストして、あなたのモジュールがflaskアプリケーションと100%互換性があることを確認してください。

関連する問題