0

私が持っているもの: 複数の同一のデータベースと SQL-Alchemy のセットアップ。

私が達成する必要があるのは、すべてのデータベースを照会できる単一の「Flask」関数です。他のすべての機能は、1 つのデータベースにのみアクセスする必要があります。

DB は既に存在し、そこからデータをロードしています。

最初は、Flask モデルを使用せずに、SQL-Alchemy 抽象化レイヤーのみを使用していました。コードは次のようになります。

app = Flask(__name__)
app.config.from_object('myflaskapp.config.settings')
metadata = None

def connect_db():
    engine = create_engine(app.config['DATABASE_URI'])
    global metadata
    metadata = MetaData(bind=engine)
    return engine.connect()

@app.before_request
    def before_request():
    g.db = connect_db()

@app.after_request
    def after_request(response):
    close_connection()
    return response

settings.py で宣言されている DATABASE_URI です。問題ではないと思いますが、基礎となる DB は Mysql サーバーであり、DATABASE_URI は次のようになります。

DATABASE_URI = 'mysql://' + dbuser + ':' + dbpass + '@' + dbhost + '/' +dbname

上記のコードにより、次のようなものを書くことができます。

myTable = Table('branch', metadata, autoload=True)
myBranch = select([myTable])

これは非常に便利です。複数の DB を扱う必要がない限り、このアプローチは問題なく機能します。より正確には、まったく同じ構造を持つ複数の DB に属するデータを (同じ関数内から) 表示したいと思います。同じクエリを任意の DB に対して正常に実行できることを意味します。擬似コード:

@app.route('/summary')
def summary():
     ....
     allData = []
     for db in all_of_my_dbs:
         allData.append(db.query())
     ....
sendToTemplate(allData) 

それは実行可能なものですか?それは実現可能ですか?ありがとうございました。

4

3 に答える 3

0

それは間違いなく可能です。

このようなものを設定ファイルに追加してみてください

SQLALCHEMY_BINDS = {
    'users':        'mysqldb://localhost/users',
    'appmeta':      'sqlite:////path/to/appmeta.db'
}

編集

だからここに作業コピー/貼り付けの例があります

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.debug = True

databases = {
    'sqlite1': 'sqlite:///sqlite1.db',
    'sqlite2': 'sqlite:///sqlite2.db'
}
app.config['SQLALCHEMY_BINDS'] = databases
db = SQLAlchemy(app)

class Thing(db.Model):
    __tablename__ = "sqlite1"
    thing_id = db.Column(db.Integer, primary_key=True)
    thing_val = db.Column(db.String(40))

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

class Thing2(db.Model):
    __tablename__ = "sqlite2"
    thing_id = db.Column(db.Integer, primary_key=True)
    thing_val = db.Column(db.String(40))

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


if __name__ == "__main__":

    db.create_all()
    t1 = Thing("test1")
    t2 = Thing2("test2")

    db.session.add(t1)
    db.session.add(t2)
    db.session.commit()

    t1 = Thing.query.filter_by(thing_id=1).first()
    t2 = Thing2.query.filter_by(thing_id=1).first()

    print t1.thing_val
    print t2.thing_val
于 2013-03-21T18:38:08.110 に答える
0

どうやらその問題にはバグがあるようです - https://github.com/mitsuhiko/flask-sqlalchemy/pull/222したがって、問題はバインドキーが一意である必要があり、1 つのクラスにしか使用できないことです (少なくとも今のところ) )、したがって、複数のデータベースを持つことはできますが、各データベースには1つのテーブルまたはクラスしか持てませんが、多くのテーブルがまだある場合、これは少なくとも今のところ単なる回避策です...

ここに「バインド」のリファレンスがあります - http://flask-sqlalchemy.pocoo.org/2.0/binds/#binds

以下は構成です。

SQLALCHEMY_DATABASE_URI = 'sqlite://///main.db'

SQLALCHEMY_BINDS= { 'table1':'sqlite://///DB1.db', 'table2':'sqlite://///DB2.db', }

以下はモデルです:

クラス table1(db.Model):

__tablename__ = "table1"
__bind_key__='table1'

クラス table2(db.Model):

__tablename__ = "table2"
__bind_key__='table2'
于 2015-07-17T21:05:40.437 に答える
0

最初に、私自身の状況についていくつか述べたいと思います。2 つのテーブルは同じ名前、同じ DDL を持ちますが、異なるスキーマ/データベースに属します。

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)

databases = {
    'sqlite1': 'sqlite:///sqlite1.db',
    'sqlite2': 'sqlite:///sqlite2.db'
}

app.config['SQLALCHEMY_BINDS'] = databases
db = SQLAlchemy(app)

class Thing(db.Model):
    __tablename__ = "mytable"
    __bind_key__ = 'sqlite1'
    thing_id = db.Column(db.Integer, primary_key=True)
    thing_val = db.Column(db.String(40))

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


if __name__ == "__main__":

    t1 = Thing.query.filter_by(thing_id=1).first()
    print t1.name

最初のクラス定義の直後に Thing2 という名前の 2 番目のクラスを追加すると、すべてが壊れます。すなわち:

class Thing(db.Model):
    __tablename__ = "mytable"
    __bind_key__ = 'sqlite1'
    thing_id = db.Column(db.Integer, primary_key=True)
    thing_val = db.Column(db.String(40))

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


class Thing2(db.Model):
    __tablename__ = "mytable"
    __bind_key__ = 'sqlite2'
    thing_id = db.Column(db.Integer, primary_key=True)
    thing_val = db.Column(db.String(40))

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

上記のコードは次のエラーで壊れます。

InvalidRequestError: テーブル 'mytable' は、この MetaData インスタンスに対して既に定義されています。'extend_existing=True' を指定して、既存のテーブル オブジェクトのオプションと列を再定義します。

そのため、フレームワークはそれらの 2 つを区別できないようです。

于 2013-03-24T18:11:27.107 に答える