tabla de mapas sqlalchemy de la base de datos mssql con “prefix-namespaces”

He estado luchando en esto por un tiempo y aún no he encontrado una respuesta, o tal vez ya la he visto y no la he recibido, pero espero poder describir mi problema.

Tengo una base de datos MS SQL en la que las tablas se agrupan en espacios de nombres (o como se llame), denotadas por Prefijo. Nombre de archivo (con un punto). Así que una statement SQL nativa para solicitar algo de contenido se ve así:

SELECT TOP 100 [Value], [ValueDate] FROM [FinancialDataBase].[Reporting].[IndexedElements] 

¿Cómo mapear esto a sqlalchemy? Si el prefijo “Reporte” no estuviera allí, la solución (o una forma de hacerlo) se ve así:

 from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base, declared_attr from sqlalchemy.orm import sessionmaker def get_session(): from urllib.parse import quote_plus as urllib_quote_plus server = "FinancialDataBase.sql.local" connstr = "DRIVER={SQL Server};SERVER=%s;DATABASE=FinancialDataBase" % server params = urllib_quote_plus(connstr) base_url = "mssql+pyodbc:///?odbc_connect=%s" % params engine = create_engine(base_url,echo=True) Session = sessionmaker(bind=engine) session = Session() return engine, session Base = declarative_base() class IndexedElements(Base): __tablename__ = "IndexedElements" UniqueID = Column(String,primary_key=True) ValueDate = Column(DateTime) Value = Column(Float) 

Y luego las solicitudes se pueden hacer y envolver en un dataframe de Pandas, por ejemplo, como este:

 import pandas as pd engine, session = get_session() query = session.query(IndexedElements.Value,IndexedElements.ValueDate) data = pd.read_sql(query.statement,query.session.bind) 

Pero la statement SQL que se comstack y ejecuta realmente en esto, incluye esta parte DESDE incorrecta:

 FROM [FinancialDataBase].[IndexedElements] 

Debido al prefijo de espacio de nombres tendría que ser

 FROM [FinancialDataBase].[Reporting].[IndexedElements] 

Simplemente expandiendo el nombre de la tabla a

 __tablename__ = "Reporting.IndexedElements" 

no lo arregla, porque cambia la sentencia comstackda de SQL a

 FROM [FinancialDataBase].[Reporting.IndexedElements] 

que no funciona correctamente.

Entonces, ¿cómo se puede resolver esto?

La respuesta está dada en el comentario de Ilja arriba:

El “espacio de nombres” es un llamado esquema y debe declararse en el objeto asignado. Dado el ejemplo de la publicación de apertura, la tabla asignada debe definirse así:

 class IndexedElements(Base): __tablename__ = "IndexedElements" __table_args__ = {"schema": "Reporting"} UniqueID = Column(String,primary_key=True) ValueDate = Column(DateTime) Value = Column(Float) 

O defina una clase base que contenga estas informaciones para diferentes esquemas. Consulte también “Aumentar la base” en los documentos de sqlalchemy: http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/mixins.html#augmenting-the-base