DoggieMurr
@DoggieMurr
Python Enthusiast

Как правильно реализовать связь в бд для GraphQL?

models.py
from sqlalchemy import (
    Column,
    ForeignKey,
    Integer,
    String, select
)
from sqlalchemy.orm import declarative_base, relationship, sessionmaker, scoped_session
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_scoped_session

DATABASE_URL = 'postgresql+asyncpg://postgres:root@localhost/aiohttp-graph'

engine = create_async_engine(DATABASE_URL, future=True, echo=True)
async_session = sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)
Base = declarative_base()


class Hall(Base):
    __tablename__ = 'halls'

    id = Column(Integer, primary_key=True)
    city = Column(String, nullable=False)
    street = Column(String, nullable=False)

    def __str__(self):
        return f'Hall in city {self.city} on street {self.street}'


class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

    def __str__(self):
        return f'User: {self.name}'


class Lesson(Base):
    __tablename__ = 'lessons'

    id = Column(Integer, primary_key=True)

    hall_id = Column(Integer, ForeignKey('halls.id'), nullable=False)
    hall = relationship('Hall',
                        backref='hall',
                        foreign_keys=[hall_id])
    coach_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    coach = relationship('User', backref='coach', foreign_keys=[coach_id])

    def __str__(self):
        return f'Lesson in {self.hall} with coach {self.coach}'


schema.py
import graphene
from graphene_sqlalchemy import SQLAlchemyObjectType
from sqlalchemy import select, join, outerjoin

import models


class Hall(graphene.ObjectType):
    id = graphene.Int()
    city = graphene.String()
    street = graphene.String()


class User(graphene.ObjectType):
    id = graphene.Int()
    name = graphene.String()


class Lesson(graphene.ObjectType):
    id = graphene.Int()
    hall = graphene.Field(Hall)
    coach = graphene.Field(User)


class Query(graphene.ObjectType):
    get_all_lessons = graphene.List(Lesson)
    get_all_users = graphene.List(User)

    @staticmethod
    async def resolve_get_all_lessons(root, info):
        async with models.async_session() as session:
            q = select(models.Lesson).\
                join(models.Hall, models.Hall.id == models.Lesson.hall_id).\
                join(models.User, models.User.id == models.Lesson.coach_id)
            result = await session.execute(q)

            return result.scalars()


schema = graphene.Schema(query=Query)


Когда делаю запрос к модели где нет связей, то все работает ок, но когда хочу получить данные где используеться свять один ко многим выскакивает ошибка:
"errors": [
    {
      "message": "Parent instance <Lesson at 0x1079a3b90> is not bound to a Session; lazy load operation of attribute 'hall' cannot proceed (Background on this error at: https://sqlalche.me/e/14/bhk3)"


Скорее всего надо что-то сделать либо с запросом либо с моделью
  • Вопрос задан
  • 130 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы