Esiste un modo conveniente per alias solo le colonne in conflitto quando si uniscono le tabelle in SQLAlchemy?

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

  •  06-07-2019
  •  | 
  •  

Domanda

A volte è utile mappare una classe su un join anziché su una singola tabella quando si utilizza Estensione dichiarativa di SQLAlchemy . Quando i nomi delle colonne si scontrano, di solito in uno-a-molti perché tutte le chiavi primarie sono denominate id per impostazione predefinita, è possibile utilizzare .alias () per aggiungere il prefisso a ogni colonna con il relativo nome della tabella. Ciò è scomodo se hai già scritto codice che presume che la tua classe mappata abbia nomi non prefissati.

Ad esempio:

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 ha id , fkey con ciascuna mappatura dei nomi sulla prima tabella nel join che utilizza il nome sovrascritto, quindi la mappata La classe non espone la chiave primaria di t2 . ST2 ha le proprietà t1_id , t2_id e t2_fkey .

Esiste un modo conveniente per alias solo alcune delle colonne di ciascuna tabella nel join in modo che la classe mappata esponga i nomi di proprietà non prefissati più convenienti per la maggior parte delle colonne mappate?

È stato utile?

Soluzione

Puoi creare un alias per ogni colonna separatamente con il suo metodo label () . Quindi è possibile qualcosa di simile al seguente (non testato):

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))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top