2013-03-21 3 views
0

Что у меня: несколько идентичных баз данных и установка SQL-Alchemy.Обслуживание страницы с несколькими базами данных

Что мне нужно для достижения: единственная функция «Колба», способная запросить все данные. Все остальные функции должны иметь доступ только к одной из баз данных.

БД уже существуют, и я загружаю данные из них.

Первоначально я использовал только слой абстракции SQL-Alchemy, без какой-либо модели Flask. Вот как выглядел код:

app = Flask(__name__) 
app.config.from_object('myflaskapp.config.settings') 
metadata = None 

def connect_db(): 
    engine = create_engine(app.config['DATABASE_URI']) 
    global metadata 
    metadata = MetaData(bind=engine) 
    return engine.connect() 

@app.before_request 
    def before_request(): 
    g.db = connect_db() 

@app.after_request 
    def after_request(response): 
    close_connection() 
    return response 

DATABASE_URI, указанный в settings.py. Я думаю, не имеет значения, однако основной БД является сервером Mysql и DATABASE_URI выглядит следующим образом:

DATABASE_URI = 'mysql://' + dbuser + ':' + dbpass + '@' + dbhost + '/' +dbname 

Приведенный выше код позволяет мне написать что-то вроде этого:

myTable = Table('branch', metadata, autoload=True) 
myBranch = select([myTable]) 

что весьма удобно. Этот подход работает отлично, если только мне не приходится иметь дело с более чем одной БД. Чтобы быть более точным, я хотел бы показать (из той же функции) данные, принадлежащие нескольким БД, которые имеют точно такую ​​же структуру. Это означает, что один и тот же запрос может успешно выполняться снова с любой БД. В псевдокоде:

@app.route('/summary') 
def summary(): 
    .... 
    allData = [] 
    for db in all_of_my_dbs: 
     allData.append(db.query()) 
    .... 
sendToTemplate(allData) 

Это что-то выполнимое? Возможно ли это? Спасибо.

ответ

0

Это определенно possible.

Попробуйте добавить что-то вроде этого в настройках файл

SQLALCHEMY_BINDS = { 
    'users':  'mysqldb://localhost/users', 
    'appmeta':  'sqlite:////path/to/appmeta.db' 
} 

Редактировать

Так вот пример рабочая копия/паста

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 

app = Flask(__name__) 
app.debug = True 

databases = { 
    'sqlite1': 'sqlite:///sqlite1.db', 
    'sqlite2': 'sqlite:///sqlite2.db' 
} 
app.config['SQLALCHEMY_BINDS'] = databases 
db = SQLAlchemy(app) 

class Thing(db.Model): 
    __tablename__ = "sqlite1" 
    thing_id = db.Column(db.Integer, primary_key=True) 
    thing_val = db.Column(db.String(40)) 

    def __init__(self, thing_val): 
     self.thing_val = thing_val 

class Thing2(db.Model): 
    __tablename__ = "sqlite2" 
    thing_id = db.Column(db.Integer, primary_key=True) 
    thing_val = db.Column(db.String(40)) 

    def __init__(self, thing_val): 
     self.thing_val = thing_val 


if __name__ == "__main__": 

    db.create_all() 
    t1 = Thing("test1") 
    t2 = Thing2("test2") 

    db.session.add(t1) 
    db.session.add(t2) 
    db.session.commit() 

    t1 = Thing.query.filter_by(thing_id=1).first() 
    t2 = Thing2.query.filter_by(thing_id=1).first() 

    print t1.thing_val 
    print t2.thing_val 
+0

Я уже видел эту ссылку по причинам, которые теперь ускользнули от меня, и я думал, что это не соответствует моим потребностям. Попробует завтра. Спасибо за ответ. –

+0

Похоже, что он делает –

+0

Похоже, это не то, что мне нужно. Или, по крайней мере, я не могу понять, как связать намеки, содержащиеся на этой странице, с тем, что мне нужно. –

0

Сначала я хотел бы отметить пару вещей, касающихся моей собственной ситуации. Две таблицы имеют одно и то же имя, то же DDL, но принадлежат к различным схемам/базе данных.

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 

app = Flask(__name__) 

databases = { 
    'sqlite1': 'sqlite:///sqlite1.db', 
    'sqlite2': 'sqlite:///sqlite2.db' 
} 

app.config['SQLALCHEMY_BINDS'] = databases 
db = SQLAlchemy(app) 

class Thing(db.Model): 
    __tablename__ = "mytable" 
    __bind_key__ = 'sqlite1' 
    thing_id = db.Column(db.Integer, primary_key=True) 
    thing_val = db.Column(db.String(40)) 

    def __init__(self, thing_val): 
     self.thing_val = thing_val 


if __name__ == "__main__": 

    t1 = Thing.query.filter_by(thing_id=1).first() 
    print t1.name 

Момент, когда я добавляю второй класс под названием Thing2 сразу после определения первого класса, все бьет. Т.е .:

class Thing(db.Model): 
    __tablename__ = "mytable" 
    __bind_key__ = 'sqlite1' 
    thing_id = db.Column(db.Integer, primary_key=True) 
    thing_val = db.Column(db.String(40)) 

    def __init__(self, thing_val): 
     self.thing_val = thing_val 


class Thing2(db.Model): 
    __tablename__ = "mytable" 
    __bind_key__ = 'sqlite2' 
    thing_id = db.Column(db.Integer, primary_key=True) 
    thing_val = db.Column(db.String(40)) 

    def __init__(self, thing_val): 
     self.thing_val = thing_val 

Приведенный выше код порывает с этой ошибкой:

InvalidRequestError: Таблица 'туЬаЫе' уже определено для этого экземпляра MetaData. Укажите «extend_existing = True», чтобы переопределить параметры и столбцы в существующем объекте Table.

Таким образом, структура, похоже, не в состоянии отличить двух из них.

0

По всей видимости, есть ошибка в этой проблеме - https://github.com/mitsuhiko/flask-sqlalchemy/pull/222, поэтому проблема заключается в том, что ключ привязки должен быть уникальным и может использоваться только для одного класса (по крайней мере пока), поэтому у вас все еще может быть несколько баз данных, но каждая база данных может иметь только одну таблицу или класс, но это, кажется, имеют огромные накладные расходы, если вы много столов до сих пор это лишь временное решение, по крайней мере на данный момент ...

здесь ссылка на «Персональный» - http://flask-sqlalchemy.pocoo.org/2.0/binds/#binds

Ниже приведена конфигурация:

SQLALCHEMY_DATABASE_URI = 'sqlite: ///// main .DB»

SQLALCHEMY_BINDS = { 'Table1': 'SQLite: /////DB1.db', 'table2': 'SQLite: /////DB2.db', }

и ниже является модель:

класс таблица1 (db.Model):

__tablename__ = "table1" 
__bind_key__='table1' 

класс таблица2 (db.Model):

__tablename__ = "table2" 
__bind_key__='table2'