query create python sqlalchemy

python - create - SQLAlchemy y mĂșltiples bases de datos



sqlalchemy python (2)

Tengo una variedad de bases de datos similares (pero no idénticas) y me gustaría usar SQLAlchemy como una manera de "estandarizar" el acceso. Las bases de datos pueden diferir muy levemente, como tener un prefijo único en los nombres de las columnas, o pueden diferir más dramáticamente y faltar columnas (o para bases de datos antiguas, sin tablas completas).

Lo que busco ayuda no es tanto un problema de SQLAlchemy, ya que es Python / Organizacional. ¿Cómo puedo tener una configuración de múltiples bases de datos que se pueda reutilizar en proyectos fácilmente?

He leído sobre las sesiones de SQLAlchemy, pero no puedo ver una forma de usarlas sin crear una instancia de cada uno de ellos en cada proyecto.

Mi pregunta es esta: ¿cómo puedo hacer un módulo / paquete que contendrá muchas configuraciones de modelo de base de datos para ser utilizado en SQLAlchemy que pueda ser fácilmente importado / utilizado en otro proyecto de python?

No estoy tan preocupado por lidiar con las columnas / tablas que faltan hasta el momento. Puedo abordar ese problema más adelante, pero es algo que debe tenerse en cuenta ya que no puedo usar el mismo modelo exacto para cada base de datos.

Cualquier recurso, punteros o material de lectura sobre este tema sería realmente apreciado. Gracias de antemano, y lo siento si esto se ha respondido en otro lugar, las búsquedas no mostraron nada relacionado con esto.

EDITAR : He dejado el original intacto y estoy agregando más contenido según los consejos de Paul.

RE: SA ORM: Sí, planeo usar SQLAlchemy ORM. Por lo que probablemente sean razones obvias, no puedo proporcionar bases de datos reales. Sin embargo, asuma estas tres bases de datos ficticias, apropiadamente llamadas DB1, DB2 y DB3 (asumiremos una tabla en cada una, con solo unas pocas columnas, el mundo real tendría significativamente más de ambas).

Cada base de datos tiene una tabla de usuarios con algunas columnas en cada una. La siguiente es una notación SQL para las tablas / columnas:

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

En este momento, estoy tratando de separar estas bases de datos a ''modular'', y ser capaz de agregar bases de datos adicionales a medida que avanzo.

Considero un par de aspectos diferentes de organización de archivos (supongamos que __init__.py existe donde sea necesario, pero se omite por brevedad), que incluye:

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

Me encantaría poder acceder a estos con el SA ORM, y hacerlo con la menor cantidad posible de importaciones / declaraciones cuando llegue el momento de utilizar estas bases de datos en un archivo python. Necesitando hacer algo similar a:

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)()

sería increíblemente engorroso ya que trataré con mucho más que solo tres bases de datos. Preferiría que ya me ocupara de eso (en el archivo __init__.py, ¿no?)

Poder acceder y usarlo de forma similar a:

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

sería infinitamente mejor

EDIT2 : También sé cómo evitar las variantes en las convenciones de nomenclatura de las bases de datos / columnas al configurar mis modelos. Eso no es un problema, pero lo mencioné para que se supiera que no puedo usar un solo conjunto de modelos para múltiples bases de datos.

Espero que expandiendo esto no enturbiera las aguas ni lo haga demasiado confuso. ¡Gracias por tomarse el tiempo de leerlo!

EDIT3 : me las arreglé para dedicar un poco más de tiempo a esto. Configuré el proyecto de la siguiente manera:

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

En este momento, tengo un tupple de bases de datos que están ''instaladas'' en el archivo settings.py. Cada entrada es como INSTALLED_DATABASES = (''DB1'', ..., ''DB3'') . A medida que complete más modelos, se agregan a la lista de tupples. Esto me permite agregar o eliminar contenido a medida que avanzo.

Tengo el motor y la configuración sessios dentro del archivo models.py, y tengo el archivo init.py para cada configuración de la base de datos a from models import * .

En el archivo databases.py tengo lo siguiente

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

Ahora puedo usar estos a través de:

from databases import Databases db = Databases() for qr in db.DB1.query(db.DB1.User): print qr.userid, qr.username

SQLAlchemy me permite especificar manualmente los nombres de las columnas al definir los modelos, lo que es una gran ventaja para la estandarización que quería.

Todavía tengo mucho trabajo por delante. Me gustaría crear objetos que fuercen la validación del modelo (es decir, ¿hay un campo presente? ¿Un campo no presente tiene un valor predeterminado? Etc.) e incorporar mejor cómo funciona esto con mi IDE (en este momento no es así) ) Pero estoy en el camino correcto. Pensé que actualizaría esto para cualquiera que, por casualidad, se esté preguntando cómo hacer lo mismo que yo.

¡Lo siento, esto se ha vuelto tan largo!

¡Aclamaciones!


Tu solución se ve bastante bien. Esto es lo que hice.

Tengo un paquete llamado conectores, y en él un módulo para cada archivo de configuración así como un archivo de configuración.

Cada uno de estos módulos de conector crea su cadena de conexión y su motor, junto con la base declarativa y las clases para las tablas.

Luego hay un método loadSession que devuelve la sesión (esta que obtuve de un tutorial u otra publicación aquí en alguna parte, no puedo recordar exactamente) y otra que agregue que devuelve el motor en caso de que quiera hacer algo con eso.

Entonces en algún otro módulo del programa, haría algo como esto

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(...)


De acuerdo con las solicitudes a mi pregunta inicial, tomé mi tercera edición y la convertí en mi respuesta. Como no estoy seguro de los protocolos adecuados, he dejado la tercera edición en su lugar más arriba. Si ya ha leído EDIT3, entonces ha leído lo que tengo como respuesta.

He logrado pasar un poco más de tiempo en esto. Configuré el proyecto de la siguiente manera:

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

En este momento, tengo un tupple de bases de datos que están ''instaladas'' en el archivo settings.py. Cada entrada es como INSTALLED_DATABASES = (''DB1'', ..., ''DB3'') . A medida que complete más modelos, se agregan a la lista de tupples. Esto me permite agregar o eliminar contenido a medida que avanzo.

Tengo el motor y la configuración sessios dentro del archivo models.py, y tengo el archivo init.py para cada configuración de la base de datos a from models import * .

En el archivo databases.py tengo lo siguiente

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

Ahora puedo usar estos a través de:

from databases import Databases db = Databases() for qr in db.DB1.query(db.DB1.User): print qr.userid, qr.username

SQLAlchemy me permite especificar manualmente los nombres de las columnas al definir los modelos, lo que es una gran ventaja para la estandarización que quería.

Todavía tengo mucho trabajo por delante. Me gustaría crear objetos que fuercen la validación del modelo (es decir, ¿hay un campo presente? ¿Un campo no presente tiene un valor predeterminado? Etc.) e incorporar mejor cómo funciona esto con mi IDE (en este momento no es así) ) Pero estoy en el camino correcto. Pensé que actualizaría esto para cualquiera que, por casualidad, se esté preguntando cómo hacer lo mismo que yo.

¡Lo siento, esto se ha vuelto tan largo!

¡Aclamaciones!