在flask-sqlalchemy中使用具有相同模型的多个数据库

时间:2017-08-14 13:15:33

标签: python mysql flask flask-sqlalchemy flask-restful

所以我有多个数据库。 DB_USDB_UK。它们具有完全相同的结构,但它们保存不同国家的数据。我有一个带有flask_restful的api。端点接受一个国家/地区来检索此特定国家/地区的数据。

我的问题是我无法弄清楚如何根据请求选择数据库。我已经阅读了bind方法,但您必须为每个模型指定一个__bind_key,并且我的所有模型都在两个数据库中。

我尝试在@before_request内初始化数据库,但在处理完第一个请求后,您无法调用init_db方法(或任何设置方法)。

这是一个特例,因为数据库是相同的,因此将它放在同一个数据库中似乎是有意义的,但它是更大系统的一部分,需要这样。

我如何根据每个请求选择数据库?

2 个答案:

答案 0 :(得分:1)

我有同样的问题。我已经在这里Using multiple POSTGRES databases and schemas with the same Flask-SQLAlchemy model

进行了描述

您的案例要容易一些,因为您不必处理架构差异。 您可以做些讨人喜欢的建议,但是问题是每个国家/地区都创建了新的用户模型(如果您的国家/地区超过2个,则会变得很混乱)。

要解决此问题,我停止使用flask-sqlAlchemy db实例化方法,并让内容提供者init方法处理要选择的数据库:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

Session = sessionmaker()

class ContentProvider():

    db = None
    connection = None
    session = None

    def __init__(self, center):
        if center == UK:
            self.db = create_engine('sqlite://UK', echo=True, pool_threadlocal=True)
            self.connection = self.db.connect()
        elif center == US:
            self.db = create_engine('sqlite://US', echo=True, pool_threadlocal=True)
            self.connection = self.db.connect()
        self.session = Session(bind=self.connection)

    def index(country):
        user = models[country]["User"](username=country + str(time.time()))
        self.session.add(user)
        self.session.commit()
        return country, "added"

答案 1 :(得分:0)

也许您可以定义一些基础数据模型并将其继承到单独的数据库中。例如:

class User(db.Model):

    __abstract__ = 1

    # fields define

class UserUK(User):

    __bind_key__ = 'uk'

class UserUS(User):

    __bind_key__ = 'us'

您可以创建一个model = {"uk": {"User": UserUK}, "us": {"User": UserUS}}的字典,以便根据请求按国家/地区选择合适的型号。例如:model[country]["User"]

完整演示:

import time
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////path/2/default.db"
app.config["SQLALCHEMY_BINDS"] = {"uk": "sqlite:////path/2/uk.db", "us": "sqlite:////path/2/us.db"}

db = SQLAlchemy(app)


class UserBase(db.Model):

    __abstract__ = 1

    id = db.Column(db.Integer, primary_key=1)

    username = db.Column(db.String(16))


class UserUK(UserBase):

    __bind_key__ = "uk"


class UserUS(UserBase):

    __bind_key__ = "us"


models = {"uk": {"User": UserUK}, "us": {"User": UserUS}}


@app.route("/<country>")
def index(country):

    user = models[country]["User"](username=country + str(time.time()))

    db.session.add(user)

    db.session.commit()

    return country, "added"


if __name__ == "__main__":

    app.run(debug=1)