Есть ли удобный способ псевдонима только конфликтующих столбцов при объединении таблиц в SQLAlchemy? - PullRequest
3 голосов
/ 27 октября 2009

Иногда полезно сопоставить класс с join вместо одной таблицы при использовании декларативного расширения SQLAlchemy . Когда имена столбцов сталкиваются, как правило, в формате «один ко многим», так как все первичные ключи по умолчанию называются id, вы можете использовать .alias() для добавления префикса к каждому столбцу с именем таблицы. Это неудобно, если вы уже написали код, предполагающий, что у вашего сопоставленного класса есть имена без префиксов.

Например:

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 имеет свойства id, fkey, каждое имя сопоставляется с первой таблицей в соединении, в котором используется переопределенное имя, поэтому сопоставленный класс не предоставляет первичный ключ t2. ST2 имеет свойства t1_id, t2_id и t2_fkey.

Есть ли удобный способ для псевдонима только некоторых столбцов из каждой таблицы в join, поэтому сопоставленный класс предоставляет наиболее удобные имена без префиксов для большинства сопоставляемых столбцов?

1 Ответ

5 голосов
/ 28 октября 2009

Вы можете создать псевдоним для каждого столбца отдельно с помощью метода label(). Так что возможно что-то похожее на следующее (не проверено):

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