3

SQLAlchemyの宣言型拡張機能joinを使用する場合、単一のテーブルではなくクラスをマップすると便利な場合があります。すべての主キーはデフォルトで名前が付けられているため、列名が衝突する場合、通常は1対多で、すべての列の前にテーブル名を付けることができます。マップされたクラスにプレフィックスなしの名前が付いていると想定するコードをすでに記述している場合、これは不便です。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にはidfkeyオーバーライドされた名前を使用する結合の最初のテーブルにマッピングされる各名前のプロパティがあるため、マッピングされたクラスはt2の主キーを公開しません。ST2、、およびプロパティt1_idがあります。t2_idt2_fkey

joinマップされたクラスがほとんどのマップされた列のより便利なプレフィックスなしのプロパティ名を公開するように、各テーブルの一部の列のみをエイリアスする便利な方法はありますか?

4

1 に答える 1

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))
于 2009-10-28T11:13:45.053 に答える