¿Hay una manera conveniente de alias solo columnas en conflicto al unir tablas en SQLAlchemy?

StackOverflow https://stackoverflow.com/questions/1627429

  •  06-07-2019
  •  | 
  •  

Pregunta

A veces es útil asignar una clase contra una join en lugar de una sola tabla cuando se usa Extensión declarativa de SQLAlchemy . Cuando los nombres de columna chocan, generalmente en uno a muchos porque todas las claves primarias se denominan id de forma predeterminada, puede usar .alias () para prefijar cada columna con su nombre de la tabla. Eso es inconveniente si ya ha escrito código que asume que su clase asignada tiene nombres sin prefijo.

Por ejemplo:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Table, Column, Integer, ForeignKeyConstraint

Base = declarative_base()

t1 = Table('t1', 
    Base.metadata, 
    Column('id', Integer, primary_key=True))

t2 = Table('t2', 
    Base.metadata, 
    Column('id', Integer, primary_key=True),
    Column('fkey', Integer),
    ForeignKeyConstraint(['fkey'], [t1.c.id]))

class ST(Base):
    __table__ = t1.join(t2)

class ST2(Base):
    __table__ = t1.join(t2).alias()

ST tiene propiedades id , fkey con cada asignación de nombre a la primera tabla en la unión que usa el nombre anulado, por lo que La clase no expone la clave primaria de t2 . ST2 tiene las propiedades t1_id , t2_id y t2_fkey .

¿Hay una manera conveniente de alias solo algunas de las columnas de cada tabla en la join para que la clase mapeada exponga los nombres de propiedades no prefijados más convenientes para la mayoría de las columnas mapeadas?

¿Fue útil?

Solución

Puede crear alias para cada columna por separado con su método label () . Entonces es posible algo similar a lo siguiente (no probado):

from sqlalchemy import select

def alias_dups(join):
    dups = set(col.key for col in join.left.columns) & \
                set(col.key for col in join.right.columns)
    columns = []
    for col in join.columns:
        if col.key in dups:
            col = col.label('%s_%s' % (col.table.name, col.key))
        columns.append(col)
    return select(columns, from_obj=[join]).alias()

class ST2(Base):
    __table__ = alias_dups(t1.join(t2))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top