概要
結合後に結合した複数のテーブル情報を取得したい場合には all や first の返り値が少し変わるので操作に工夫が必要になります
環境
- macOS 11.7.4
- SQLAlchemy 2.0.7
SQL例
def list_user_by_sub_group_name(self, name: str) -> list[User|Group]:
return (
self.db.query(User, Group)
.join(Group, User.group_id == Group.id)
.join(SubGroup, Group.sub_group_id == SubGroup.id)
.filter(
SubGroup.name == name,
)
.all()
)
db.query で User クラスと Group テーブルを指定します
こうすることで user テーブルと group テーブルが結合された特殊な行データ (sqlalchemy.engine.row.Rowというクラス)のデータが取得できます
Row の扱い方
配列には各テーブルごとにタプルとして格納されています
rows = self.list_user_by_sub_group_name("subgroup1")
for row in rows:
user = row[0] # db.query の 1 つ目の引数で指定したクラスのデータがタプルの index=0 に格納されている
group = row[1] # db.query の 2 つ目の引数で指定したクラスのデータがタプルの index=1 に格納されている
print(user.id)
print(group.id)
注意事項
pyright などを使って型チェックしていると "__getitem__" method not defined on type "User"
というエラーが出ます
素直に __getitem__
を実装するか # type: ignore
で型チェックを無視するようにしましょう
最後に
ちょっと特殊な扱い方なので注意しましょう
0 件のコメント:
コメントを投稿