Flask унаследовал классы таблиц в нескольких идентичных базах данных, используя __bind_key__

Я пытаюсь создать панель управления администратора, которая объединяет 4 разных сайта электронной коммерции. Все сайты имеют одинаковую структуру базы данных (все MySQL).

Что происходит не так?

Я получаю 404 Not Found на любом идентификаторе заказа и сайте, который я указал. Как бы я ни смешивал его, я не могу получить какую-либо запись. Всегда 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'
}

просмотры.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 и имеют не очень аккуратную структуру и соглашения об именах.

Спасибо за ваше время.


person RustyFluff    schedule 29.07.2011    source источник
comment
Есть ли способ изменить bind_key одной модели, не определяя другую модель   -  person user1369887    schedule 18.09.2018


Ответы (2)


В настоящее время проблема с 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 простой MyModel.query.filter(...) возможен для разных баз данных, если вы правильно определили __bind_key__.

person Christopher Grebs    schedule 01.08.2011
comment
с выпуском Flask-SQLAlchemy 0.15 простой MyModel.query.filter(...) возможен для разных баз данных, если вы правильно определили _bind_key_. - person Christopher Grebs; 10.08.2011

db.Model.metadata.tables['имя вашей модели'].info['bind_key'] = 'ваше имя_привязки'

Я нашел способ упростить задачу

person user1369887    schedule 18.09.2018
comment
Какую версию flask_sqlalchemy вы используете? - person Francois; 01.11.2018