База данных Multi с тем же именем таблицы в flask_sqlalchemy - PullRequest
0 голосов
/ 20 марта 2020

У меня есть несколько баз данных, например order_db1order_db2order_db3,

, но все они имеют таблицу order, но данные в order_db1.order отличаются от order_db2.order,

order_db1.order

| id | сумма |

| 1 | 100 |

order_db2.order

| id | сумма |

| 1 | 200 |

как я могу получить доступ к мульти-базе данных с тем же именем таблицы в flask_sqlalchemy?

Я пробовал вот так , использовать SQLALCHEMY_BINDS

# -*- coding: utf-8 -*-
from flask import Flask

from flask_sqlalchemy import SQLAlchemy
import logging


class Application(Flask):
    def __init__(self, import_name):
        super(Application, self).__init__(import_name)

app = Application(__name__)
db = SQLAlchemy(app)
app.config['SQLALCHEMY_BINDS'] = {
'order_db1': 'mysql://%s:%s@%s/order_db1' % (mysql_user, quote_plus(mysql_pwd),mysql_host),
'order_db2': 'mysql://%s:%s@%s/order_db2' % (mysql_user, quote_plus(mysql_pwd),mysql_host),
}


class Order1(db.model):
    __bind_key__ = 'order_db1'
    __tablename__ = 'order'
    id = db.colum(db.Interger)
    amount = db.colum(db.Interger)

class Order2(db.model):
    __bind_key__ = 'order_db2'
    __tablename__ = 'order'
    id = db.colum(db.Interger)
    amount = db.colum(db.Interger)

q1=Order1.query.get(1)
q2=Order2.query.get(1)

It сказал мне:

'sqlalchemy.ex c .InvalidRequestError: Таблица' order 'уже определена для этого экземпляра MetaData. Укажите 'extension_existing = True', чтобы переопределить параметры и столбцы в существующем объекте таблицы. '

Но если я добавлю __table_args = {'extend_existing': True}


class Order1(db.model):
    __bind_key__ = 'order_db1'
    __tablename__ = 'order'
    __table_args = {'extend_existing': True}

    id = db.colum(db.Interger)
    amount = db.colum(db.Interger)


class Order2(db.model):
    __bind_key__ = 'order_db2'
    __tablename__ = 'order'
    __table_args = {'extend_existing': True}

    id = db.colum(db.Interger)
    amount = db.colum(db.Interger)

q1=Order1.query.get(1)
q2=Order2.query.get(1)

, данные в q1 будут такими же q2, значит id = 1, сумма = 200

Я хочу это как:

q1: id = 1, сумма = 100

q2: id = 1, сумма = 200

1 Ответ

0 голосов
/ 21 марта 2020

Известны проблемы с привязками и одинаковыми именами таблиц. См. Это обсуждение и этот возможный обходной путь .

Альтернативным обходным решением является использование двух Sqlalchemy экземпляров, которые могут быть или не приемлемы для вашего варианта использования. Смотрите пример отдельного файла с использованием SQLite.

import random
from flask import Flask, render_template_string
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_BINDS'] = {
    'order_db1': 'sqlite:///order_db1.sqlite',
    'order_db2': 'sqlite:///order_db2.sqlite',
}

db1 = SQLAlchemy(app)
db2 = SQLAlchemy(app)


class Order1(db1.Model):
    __bind_key__ = 'order_db1'
    __tablename__ = 'order'

    id = db1.Column(db1.Integer, primary_key=True)
    amount = db1.Column(db1.Integer)


class Order2(db2.Model):
    __bind_key__ = 'order_db2'
    __tablename__ = 'order'

    id = db2.Column(db2.Integer, primary_key=True)
    amount = db2.Column(db2.Integer)


_html_template = '''
        <p>Order 1 count:{{order_1_count}}</p>
        <p>Order 2 count:{{order_2_count}}</p>
    '''


@app.route('/')
def index():
    order_1_count = Order1.query.count()
    order_2_count = Order2.query.count()

    return render_template_string(_html_template, order_1_count=order_1_count, order_2_count=order_2_count)


@app.before_first_request
def build_sample_db():

    db1.drop_all()
    db2.drop_all()

    db1.create_all()
    db2.create_all()

    # Create 100 records in db1
    db1.session.add_all([Order1(amount=random.randint(0, 100)) for _ in enumerate(range(0, 100))])
    db1.session.commit()

    # Create 1000 records in db1
    db2.session.add_all([Order2(amount=random.randint(1000, 10000)) for _ in enumerate(range(0, 1000))])
    db2.session.commit()

    return app


if __name__ == '__main__':
    app.run()
...