使用__bind_key__在多个相同数据库中继承Flask表类
我正在尝试建立一个管理控制面板,目的是把四个不同的电商网站整合在一起。这些网站的数据库结构是完全相同的(都是MySQL)。
出什么问题了?
无论我输入哪个订单ID和网站,都会出现404未找到的错误。无论我怎么组合,都无法找到任何记录。总是404错误,我也不知道为什么。所以我在这里求助。
代码
我尝试通过为每个表创建基础模型类来实现这个目标。然后根据不同的数据库,创建这些基础类的子类,使用不同的绑定键。这是代码的简要概述——如果你需要更多信息,请告诉我:
basemodels.py
MyOrderClass(db.Model):
__tablename__ = 'messytablename'
id = db.Column('order_id', db.Integer, primary_key=True)
order_total = db.Column(db.Float)
order_status = db.Column(db.String(1))
site2models.py
class Site2Order(MyOrderClass):
__bind_key__ = 'site2'
__init__.py
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user:pass@localhost/site'
app.config['SQLALCHEMY_BINDS'] = {
'site1':'mysql://user:pass@localhost/site1',
'site2':'mysql://user:pass@localhost/site2',
'site3':'mysql://user:pass@localhost/site3',
'site4':'mysql://user:pass@localhost/site4'
}
views.py
@app.route('/order/<site>/<orderid>')
def show_order(site, orderid):
if site == 'site1':
orderObject = Site1Order
if site == 'site2':
orderObject = Site2Order
if site == 'site3':
orderObject = Site3Order
if site == 'site4':
orderObject = Site4Order
order = orderObject.query.get(orderid)
return render_template('order.html', order=order)
原始网站是用PHP构建的,结构和命名规范都不太整洁。
感谢你的时间。
2 个回答
1
db.Model.metadata.tables['你的模型名称'].info['绑定键'] = '你的绑定名称'
我找到了一种简单的方法
3
现在关于SQLALCHEMY_BINDS的问题是,它只在像create_all()或drop_all()这样的操作中使用。你需要为这些操作更改会话绑定:
db.session.bind = db.get_engine(app, 'site2')
目前正在进行一些工作来改变这一点,但还没有正式发布。
你的代码可以像这样:
db.session.bind = db.get_engine(app, orderObject.__bind_key__)
order = orderObject.query.get(orderid)
但要记住,这会改变全局会话,并不会重置它。你需要自己去重置,或者写一个上下文管理器,这样你就可以使用with
语句来处理。
如果你的模型在所有数据库中都是一样的,这也可以让你只用一个类来处理所有数据库,只需保留bind_key,然后用一个特殊的绑定会话对象来查询它们。
编辑:在Flask-SQLAlchemy 0.15版本中,如果你正确地定义了__bind_key__,那么对于不同的数据库,可以简单地使用MyModel.query.filter(...)。