SQLAlchemyでテーブルを結合するときに競合する列のみをエイリアスする便利な方法はありますか?

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

  •  06-07-2019
  •  | 
  •  

質問

join に対してクラスをマップすると便利な場合があります> SQLAlchemy の宣言的拡張。すべての主キーの名前はデフォルトで id であるため、通常1対多で列名が衝突する場合、 .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