Есть ли удобный способ псевдонима только конфликтующих столбцов при объединении таблиц в SQLAlchemy?

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

  •  06-07-2019
  •  | 
  •  

Вопрос

Иногда полезно сопоставить класс с 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 , чтобы отображаемый класс предоставлял более удобные имена без префиксов для большинства отображаемых столбцов?

Это было полезно?

Решение

Вы можете создать псевдоним для каждого столбца отдельно с помощью метода 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))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top