Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为具有多个数据库的页面提供服务';s_Python_Database_Sqlalchemy_Flask - Fatal编程技术网

Python 为具有多个数据库的页面提供服务';s

Python 为具有多个数据库的页面提供服务';s,python,database,sqlalchemy,flask,Python,Database,Sqlalchemy,Flask,我拥有:多个相同的数据库和一个SQL炼金术设置 我需要实现的是:一个能够查询所有数据库的“Flask”函数。所有其他函数只需要访问其中一个数据库 数据库已经存在,我正在从中加载数据 起初,我只使用SQL Alchemy抽象层,没有任何烧瓶模型。代码是这样的: app = Flask(__name__) app.config.from_object('myflaskapp.config.settings') metadata = None def connect_db(): engine

我拥有:多个相同的数据库和一个SQL炼金术设置

我需要实现的是:一个能够查询所有数据库的“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中声明数据库\u URI。我想没关系,但是底层数据库是Mysql服务器,数据库URI看起来像:

DATABASE_URI = 'mysql://' + dbuser + ':' + dbpass + '@' + dbhost + '/' +dbname
上面的代码允许我编写如下内容:

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

@app.route('/summary')
def summary():
     ....
     allData = []
     for db in all_of_my_dbs:
         allData.append(db.query())
     ....
sendToTemplate(allData) 
这是可行的吗?可行吗? 谢谢。

这绝对是个好主意

尝试将类似的内容添加到设置文件中

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

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

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”。指定“extend_existing=True”以重新定义现有表对象上的选项和列。


因此,框架似乎无法区分这两个类。

显然,在这个问题上存在一个缺陷-所以问题是绑定键必须是唯一的,并且只能用于一个类(至少目前是这样),因此,您仍然可以有多个数据库,但每个数据库只能有一个表或一个类,但如果您仍然有多个表,这似乎会有巨大的开销,至少目前这只是一种解决方法

这里是“绑定”的参考-

以下是配置:

SQLALCHEMY\u数据库\u URI='0sqlite://///main.db"

SQLALCHEMY_绑定={ “表1”:sqlite://///DB1.db', ‘表二’sqlite://///DB2.db', }

以下是模型:

类别表1(数据库模型):

类别表2(数据库模型):


我已经看到了这个链接,出于我现在无法理解的原因,我认为它不符合我的需要。我明天会试一试。谢谢你的回答。看起来这不是我需要的。或者至少我看不到如何将该页面中包含的提示与我需要的内容联系起来。@dimiziero如果我下班回家时你还没有弄明白的话。我会看看是否能找到一个有效的例子,我们不允许在工作中使用sqlalchemy=|。那太好了。如果我发现任何有用的东西,我会继续研究并更新。我很高兴让你的例子发挥作用。为什么要将bindname分配给tablename变量?我猜Thing1和Thing2的tablename应该是相同的,var\uu绑定键来自SQLALCHEMY\u绑定。谢谢你抽出时间,梅,谢谢
__tablename__ = "table1"
__bind_key__='table1'
__tablename__ = "table2"
__bind_key__='table2'