2013-03-07 5 views
24

У меня есть набор похожих (но не идентичных) баз данных и хотел бы использовать SQLAlchemy как способ «стандартизации» доступа. Базы данных могут отличаться очень незначительно, например, иметь уникальный префикс в именах столбцов или они могут отличаться более резко, а также отсутствовать столбцы (или для старых баз данных, отсутствующие целые таблицы).SQLAlchemy и несколько баз данных

Что я ищу, это не проблема SQLAlchemy, так как это Python/Organizational. Как я могу настроить несколько баз данных, которые могут быть повторно использованы в проектах?

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

Мой вопрос заключается в следующем: как я могу сделать модуль/пакет, который будет содержать множество настроек модели базы данных, которые будут использоваться в SQLAlchemy, которые могут быть легко импортированы/использованы в другом проекте python?

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

Любые ресурсы, указатели или материалы для чтения на эту тему будут по достоинству оценены. Заранее спасибо, и я сожалею, если на это ответили в другом месте, поиски не показали ничего, что связано с этим.

EDIT: Я оставил оригинал неповрежденным и добавляю больше контента на основании совета Павла.

RE: SA ORM - Да, я планирую использовать ORM SQLAlchemy. По каким-то очевидным причинам я не могу предоставить реальные базы данных. Однако предположим, что эти три фиктивные базы данных, точно названные DB1, DB2 и DB3 (мы будем предполагать одну таблицу в каждой, только с несколькими столбцами, в реальном мире будет значительно больше того и другого).

Каждая база данных имеет таблицу пользователей с несколькими столбцами в каждой. Ниже некоторые SQL обозначения для таблиц/столбцов:

DB1.user --> DB1.user.id,  DB1.user.username, DB1.user.email 
DB2.user --> DB2.user.id,  DB2.user.user_name, DB2.user.email 
DB3._user --> DB3._user.userid, DB3._user.username, DB3.user.email_address 

В настоящее время я пытаюсь отделить эти базы данных для «модульного», и иметь возможность просто добавить дополнительные базы данных, как я иду.

Я рассмотрим организации несколько другой файл аспектов (предположим, что __init__.py существует там, где это необходимо, но опущены для краткости), в том числе:

Databases   | Databases   | Databases 
    DB1.py  |  DB1    |  DB1 
    DB2.py  |   models.py |   models 
    DB3.py  |  DB2    |    user.py 
        |   models.py |    anothertable.py 
        |  DB2    |  ... 
        |   models.py |  DB3 
        |       |   models 
        |       |    user.py 
        |       |    anothertable.py 

Я хотел бы, чтобы иметь возможность доступа к ним с SA ORM, и делайте это с минимальным количеством импортирующих/деклараций, когда это возможно, когда приходит время использовать эти базы данных в файле python. Нуждаясь сделать что-то похожее на:

from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker 
from Database import DB1, ..., DB[N] 
db1_engine = create_engine('connect_string/db1') 
db1_session = sessionmaker(bind=db1_engine)() 
... 
db3_engine = create_engine('connect_string/db3') 
db3_session = sessionmaker(bind=db3_engine)() 

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

Будучи в состоянии получить доступ и использовать его похожим на (в __init__.py файл, может быть?):

import Databases 

Databases.DB1.session.query('blahblah') 

будет гораздо лучше.

EDIT2: Я также знаю, как обойти варианты в соглашениях об именах баз данных/столбцов при настройке моих моделей. Это не проблема, но я упомянул об этом так, что было известно, что я не могу просто использовать один набор моделей для нескольких баз данных.

Надеюсь, расширив это, я не мутировал воды и не делал это слишком запутанным. Спасибо, что нашли время, чтобы прочитать его!

EDIT3: Мне удалось потратить немного больше времени на это. Я создал проект следующим образом:

Databases 
    __init__.py 
    databases.py 
    settings.py 
    DB1 
     __init__.py 
     models.py 
    ... 
    DB3 
     __init__.py 
     models.py 

В настоящее время у меня есть tupple баз данных, которые «установлены» в файле settings.py. Каждой записи понравится INSTALLED_DATABASES = ('DB1', ..., 'DB3'). Когда я заканчиваю больше моделей, и они добавляются в список туферов. Это позволяет мне добавлять или удалять контент по мере поступления.

У меня есть установка двигателя и sessios в файле models.py и файл init.py для каждой настройки базы данных до from models import *.

В databases.py файле У меня есть следующие

class Databases(object): 
    def __init__(self): 
     for database in INSTALLED_DATABASES: 
      setattr(self, database, __import__(database)) 

теперь я могу использовать их с помощью:

from databases import Databases 

db = Databases() 

for qr in db.DB1.query(db.DB1.User): 
    print qr.userid, qr.username 

SQLAlchemy позволяет мне вручную указать имена столбцов при определении моделей, которые является огромным бонусом к стандартизации, которую я хотел.

У меня впереди еще много работы. Я хотел бы создать объекты, которые заставляют валидацию модели (т. Е. Присутствует ли данное поле? Имеет ли не существующее поле значение по умолчанию? И т. Д.) И лучше включить, как это работает с моей IDE (в настоящее время это не так). Но я на правильном пути. Я решил, что обновляю это для всех, кто случайно может подумать, как сделать то же самое, что и я.

Извините, это стало так долго!

Cheers!

+0

Я добавил дополнительную информацию к этому как EDIT3. У меня есть * kinda * работающий, как я этого хочу, но вам нужно будет продолжать его улучшать. Мне нужно будет продолжить работу по этой проблеме в разные вопросы, так как на объем оригинала был дан ответ. Поэтому я не ожидаю, что обновлю это, если я не изменю что-то решительное или не сделаю серьезных успехов в его работе. Если у кого-то есть предложения по тому, как это сделать лучше, я все уши. Спасибо за прочтение. – Rejected

+0

Я не уверен, что это может помочь в вашей проблеме, но, возможно, это может добавить что-то для вас. Это сообщение от zzeek, ​​и, читая ваш вопрос, мне частично напомнили об этом: http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy – javex

+0

Я бы настоятельно рекомендовал взяв последнее редактирование и сделав его ответом - он хороший, и ответ на свой вопрос улыбается здесь :-) –

ответ

5

В соответствии с запросами к моему первоначальному вопросу, я взял свою третьи редактировать и сделал это мой ответ. Поскольку я не уверен в правильных протоколах, я оставил третье редактирование на месте выше.Если вы уже прочитали EDIT3, вы прочитали, что я имею в качестве ответа.

Мне удалось потратить немного больше времени на это. Я создал проект следующим образом:

Databases 
    __init__.py 
    databases.py 
    settings.py 
    DB1 
     __init__.py 
     models.py 
    ... 
    DB3 
     __init__.py 
     models.py 

В настоящее время у меня есть tupple баз данных, которые «установлены» в файле settings.py. Каждой записи понравится INSTALLED_DATABASES = ('DB1', ..., 'DB3'). Когда я заканчиваю больше моделей, и они добавляются в список туферов. Это позволяет мне добавлять или удалять контент по мере поступления.

У меня есть установка двигателя и sessios в файле models.py и файл init.py для каждой настройки базы данных до from models import *.

В databases.py файле У меня есть следующие

class Databases(object): 
    def __init__(self): 
     for database in INSTALLED_DATABASES: 
      setattr(self, database, __import__(database)) 

теперь я могу использовать их с помощью:

from databases import Databases 

db = Databases() 

for qr in db.DB1.query(db.DB1.User): 
    print qr.userid, qr.username 

SQLAlchemy позволяет мне вручную указать имена столбцов при определении моделей, которые является огромным бонусом к стандартизации, которую я хотел.

У меня впереди еще много работы. Я хотел бы создать объекты, которые заставляют валидацию модели (т. Е. Присутствует ли данное поле? Имеет ли не существующее поле значение по умолчанию? И т. Д.) И лучше включить, как это работает с моей IDE (в настоящее время это не так). Но я на правильном пути. Я решил, что обновляю это для всех, кто случайно может подумать, как сделать то же самое, что и я.

Извините, это стало так долго!

Cheers!

1

Ваше решение выглядит довольно хорошо. Вот что я сделал.

У меня есть пакет с именем connector, а в нем модуль для каждого db, а также файл настроек.

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

Тогда есть метод loadSession, который возвращает сеанс (этот я получил из учебника или другого сообщения здесь, не могу вспомнить точно), и еще один, который я добавил, который возвращает движок, если я хочу что-то сделать с этим ,

Итак, в каком-либо другом модуле программы, я хотел бы сделать что-то вроде этого

from connectors import x, y, z 

x_ses = x.loadSession() 
y_ses = y.loadSession() 
z_ses = z.loadSession() 

xq = x_ses.query(...) 
yq = y_ses.query(...) 
Смежные вопросы