0

我有:多个相同的数据库和 SQL-Alchemy 设置。

我需要实现的是:一个能够查询所有数据库的“Flask”函数。所有其他功能只需要访问其中一个数据库。

数据库已经存在,我正在从它们加载数据。

最初我只使用 SQL-Alchemy 抽象层,没有任何 Flask 模型。这是代码的样子:

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。我想没关系,但是底层数据库是一个 Mysql 服务器和 DATABASE_URI 看起来像:

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

上面的代码允许我写这样的东西:

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

这很方便。这种方法工作得很好,除非我必须处理多个数据库。更准确地说,我想(从同一函数中)显示属于具有完全相同结构的多个数据库的数据。这意味着相同的查询可以成功地再次运行任何数据库。在伪代码中:

@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

首先,我想就我自己的情况说几件事。这两个表具有相同的名称、相同的 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 的类时,一切都崩溃了。IE:

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:已经为此 MetaData 实例定义了表“mytable”。指定 'extend_existing=True' 以重新定义现有 Table 对象上的选项和列。

所以框架似乎无法区分这两者。

于 2013-03-24T18:11:27.107 回答
0

显然在这个问题上有一个错误 - https://github.com/mitsuhiko/flask-sqlalchemy/pull/222所以问题是绑定键必须是唯一的并且只能用于一个类(至少现在),所以你仍然可以有多个数据库,但每个数据库只能有一个表或一个类,但如果你有很多表,它似乎确实有巨大的开销,至少现在这只是一种解决方法......

这是“绑定”的参考 - 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', }

以下是模型:

类表1(db.Model):

__tablename__ = "table1"
__bind_key__='table1'

类表2(db.Model):

__tablename__ = "table2"
__bind_key__='table2'
于 2015-07-17T21:05:40.437 回答