我有一个“多租户” Flask 网络应用程序,它与1个“主”MySQL数据库(用于查找客户端信息)和几十个“客户端“MySQL数据库(都具有相同的模式)。
我目前正在尝试使用 SQLAlchemy 以及 Flask-SQLAlchemy扩展程序来与数据库进行交互,但我很难找到一种方法来允许我在我的应用中定义的模型 将上下文从一个客户端数据库动态切换到另一个 ,具体取决于客户端。
在Flask-SQLAlchemy site上,一个简单的例子如下所示:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@Y.Y.Y.Y/db1'
db = SQLAlchemy(app)
class User(db.Model):
# Etc.
唯一的问题是,SQLALCHEMY_DATABASE_URI
配置是静态完成的。我可能需要在mysql://username:password@Y.Y.Y.Y/db1
和mysql://username:password@Z.Z.Z.Z/db1
(或任何其他任意MySQL URI)之间切换,具体取决于发出请求的客户端。
我发现了一些类似的问题(见下文),但在使用Flask-SQLAlchemy扩展时,我还没有找到一种干净的方法。
With sqlalchemy how to dynamically bind to database engine on a per-request basis
Flask SQLAlchemy setup dynamic URI
我还看到了一些为处理分片数据库而提供的示例(也应该适用,因为数据库本质上是由客户端逻辑分片),但同样,没有特定于Flask-SQLAlchemy。
如果有意义,我也可以直接使用SQLAlchemy,而不使用Flask-SQLAlchemy扩展。我是SQLAlchemy的新手 - 非常感谢任何帮助!
编辑:能够反映数据库中的表模式将是一个奖励。
答案 0 :(得分:2)
如果您使用flask-sqlalchemy 0.12或更高版本,则BINDS支持此功能。
SQLALCHEMY_DATABASE_URI = 'postgres://localhost/main'
SQLALCHEMY_BINDS = {
'users': 'mysqldb://localhost/users',
'appmeta': 'sqlite:////path/to/appmeta.db'
}
您可以在模型定义中指定连接数据库。
class User(db.Model):
__bind_key__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
它将使用mysqldb auto。有关详细信息,请参阅官方文档。 Multiple Databases with Binds
答案 1 :(得分:0)
You could do something like this. FYI this is pure SQLAlchemy, not with Flask-SQLAlchemy. Hopefully you need this for read-only stuff. You can figure out some other stuff to have to write stuff, like even listeners on your session/models
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# an Engine, which the Session will use for connection
# resources
some_engine_1 = create_engine('postgresql://scott:tiger@localhost/')
some_engine_2 = create_engine('postgresql://adriel:velazquez@localhost/')
# create a configured "Session" class
Session_1 = sessionmaker(bind=some_engine_1)
Session_2 = sessionmaker(bind=some_engine_2)
# create a Session
session_1 = Session_1()
session_2 = Session_2()
Base = declarative_base()
class ModelBase(Base):
#different custom queries for each database
master_query = session_1.query_property()
client_1_query = session_2.query_property()
class User(ModelBase):
pass
#ETC
##Accessing the different databases:
User.master_query.filter(User.id == 1).all()
User.client_1_query.filter(User.id == 1).all()
答案 2 :(得分:0)
您将需要使用SQLALCHEMY_BINDS方法绑定到多[le客户数据库]。
app.config['SQLALCHEMY_BINDS'] = { 'user1': mysql database', user2: mysqal2database'}
例如,您还需要在模型中引用诸如“ user1”之类的bind_key名称:
class users(db.Model):
__bind_key__
id = db.Column(Integer, primary_key=True)
name = db.Column(String)
以上这些方法是您应设置的主要SQLALCHEMY_DATABASE_URI之外的方法。虽然您可以在用户登录方法上动态绑定其他数据库。
希望这会有所帮助!