2009-10-26 1 views
3

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

Например:

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 «s первичного ключа. ST2 имеет t1_id, t2_id и t2_fkey объектов недвижимости.

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

ответ

5

Вы можете создать псевдоним для каждого столбца отдельно с помощью метода 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))