Esiste un modo conveniente per alias solo le colonne in conflitto quando si uniscono le tabelle in SQLAlchemy?
-
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?
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))