「primary_key」属性はのインスタンスでありPrimaryKeyConstraint
、その場で反復可能であるlist(table.primary_key)[0]
ため、その列で取得する必要があるのはこれだけです。
以下の例は、2つの複合互換技術を示しています(編集:「複合ではない」と言いました。とにかくクールなコードです... select_by_single_pk()を使用してください)。1つはタプルサポート(postgresql、おそらくmysql)が必要で、もう1つは文字列です。 AND / OR、および単一のPKアプローチ。次に、タプルを受け入れるquery.get()を表示します。
from sqlalchemy import tuple_, or_, and_
def select_by_composite_pk(table, values):
"works only in a high-capability database like postgresql"
return table.select().where(tuple_(*table.primary_key).in_(values))
def select_by_composite_pk_no_tuples(table, values):
"works in any database"
return table.select().where(
or_(
*[
and_(*[col == val for col, val in zip(table.primary_key, val)])
for val in values
]
))
def select_by_single_pk(table, values):
"works in any database"
return table.select().where(list(table.primary_key)[0].in_(values))
if __name__ == '__main__':
from sqlalchemy import create_engine, Table, Column, Integer, MetaData
eng = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
conn = eng.connect()
trans = conn.begin()
m = MetaData()
# single PK column
a = Table('a', m, Column('x', Integer, primary_key=True),
Column('y', Integer))
# composite PK column
b = Table('b', m, Column('x', Integer, primary_key=True),
Column('y', Integer, primary_key=True))
m.create_all(conn)
conn.execute(a.insert(), [
{'x': i, 'y': i * 2} for i in xrange(10)
])
conn.execute(b.insert(), [
{'x': i, 'y': i * 2} for i in xrange(10)
])
print conn.execute(
select_by_composite_pk(a,
[tuple_(3, ), tuple_(5, ), tuple_(9, )])).fetchall()
print conn.execute(
select_by_composite_pk(b,
[tuple_(3, 6), tuple_(5, 10), tuple_(9, 18)])).fetchall()
print conn.execute(
select_by_composite_pk_no_tuples(b,
[(3, 6), (5, 10), (9, 18)])).fetchall()
print conn.execute(
select_by_single_pk(b, [3, 5, 9])).fetchall()
# ORM query version
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class MyCompositeClass(Base):
__table__ = b
# get accepts a tuple
print Session(conn).query(MyCompositeClass).get((5, 10))