SQLAlchemyでテーブルを結合するときに競合する列のみをエイリアスする便利な方法はありますか?
-
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))
所属していません StackOverflow