I am getting an error while getting models backref related data:
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)
models.py
:
import uuid
from sqlalchemy_utils import EmailType, Timestamp, UUIDType
from sqlalchemy import Boolean, Column, ForeignKey, String, UniqueConstraint
from sqlalchemy.orm import relationship
from app.db import Base
class User(Base, Timestamp):
__tablename__ = "users"
id = Column(UUIDType(), default=uuid.uuid4, primary_key=True)
name = Column(String, nullable=False)
email = Column(EmailType, unique=True, nullable=False)
hashed_password = Column(String, nullable=False)
is_active = Column(Boolean, default=True, nullable=False)
def __repr__(self):
return f"User(id={self.id}, name={self.email})"
class Company(Base, Timestamp):
__tablename__ = "companies"
id = Column(UUIDType(binary=False), default=uuid.uuid4, primary_key=True)
name = Column(String, nullable=False)
is_active = Column(Boolean, default=True, nullable=False)
def __repr__(self):
return f"<Company(id={self.id}, name={self.name}, is_active={self.is_active})>"
class CompanyUser(Base, Timestamp):
__tablename__ = "company_users"
__table_args__ = (UniqueConstraint("company_id", "user_id", name="user_company"),)
id = Column(UUIDType(binary=False), default=uuid.uuid4, primary_key=True)
company_id = Column(
UUIDType(binary=False),
ForeignKey("companies.id", ondelete="CASCADE"),
nullable=False,
)
company = relationship(
"Company",
order_by="Company.id",
backref="company_users",
lazy="subquery",
)
user_id = Column(
UUIDType(binary=False),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
)
user = relationship(
"User",
order_by="User.id",
backref="user_companies",
lazy="subquery",
)
role = Column(String, nullable=False)
def __repr__(self):
return f"<CompanyUser(id={self.id}, company_id={self.company_id}, user_id={self.user_id}, is_active={self.is_active})>"
app/db.py
:
from typing import Any
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase
from app.core.config import settings
async_engine = create_async_engine(str(settings.ASYNC_DATABASE_URL), pool_pre_ping=True)
async_session_maker = async_sessionmaker(
async_engine,
class_=AsyncSession,
expire_on_commit=False,
autocommit=False,
autoflush=False,
)
class Base(DeclarativeBase):
id: Any
router.py
:
from fastapi import APIRouter
from sqlalchemy import select
from app.deps.db import CurrentAsyncSession
from app.deps.users import CurrentUser
from app.models import User
from app.schemas.user import UserSchema
router = APIRouter(prefix="/users")
@router.get("/me")
async def me(user: CurrentUser, session: CurrentAsyncSession) -> UserSchema:
print(user.companies)
# tried this also
user = await session.get(User, user.id)
print(user.companies)
return user
My point was to use it in schema but found that even printing in the router is not working.
What is a solution here? This wasn't a problem on Flask with sync sqlalchemy.
requirements.txt
:
fastapi==0.104.1
uvicorn==0.23.2
alembic==1.12.1
SQLAlchemy==2.0.22
pydantic-settings==2.0.3
sqlalchemy-utils==0.41.1
asyncpg==0.28.0
psycopg2==2.9.9
fastapi-users[sqlalchemy]==12.1.2