Метод join класса Query
Метод join класса Query выполняет
внутреннее соединение (INNER JOIN) основной
таблицы запроса с другой таблицей. Первым
параметром метод принимает целевую таблицу
или модель, вторым (необязательным) - условие
соединения. Если условие не указано,
SQLAlchemy пытается определить связь между
таблицами автоматически по внешнему ключу.
Синтаксис
Query.join(target, [onclause], [isouter], [full])
Пример
Давайте создадим две связанные модели
User и Article и выполним
соединение по внешнему ключу:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(User(id=1, name='user'))
session.add(Article(id=1, title='article', user_id=1))
session.commit()
res = session.query(Article).join(User).all()
for article in res:
print(article.title)
Результат выполнения кода:
"article"
Пример
Давайте явно укажем условие соединения вторым параметром:
<+python+>
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(User(id=1, name='user'))
session.add(Article(id=1, title='article', user_id=1))
session.commit()
res = session.query(Article).join(User, Article.user_id == User.id).all()
for article in res:
print(article.title)
<-python+>
Результат выполнения кода:
"article"
Пример
Давайте выполним соединение и получим поля из обеих таблиц:
<+python+>
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(User(id=1, name='user'))
session.add(Article(id=1, title='article', user_id=1))
session.commit()
res = session.query(Article.title, User.name).join(User).all()
for title, name in res:
print(title, name)
<-python+>
Результат выполнения кода:
"article user"