我收到此错误,但我不明白如何解决它。当我使用 uvicorn 运行 FastApi 时出现此错误。要注意利用循环模型导入的错误,我使用了
TYPE_CHEKING
sqlalchemy.ext.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper:
'Mapper[User(users)]'. Original exception was: When initializing mapper Mapper[User(users)], expression 'Times' failed to locate a name ('Times'). If
this is a class name, consider adding this relationship() to the <class 'app.models.user_model.User'> class after bath dependent classes have been defined.
我的模型定义如下:
class Times(Base):
__tablename__ = 'times'
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
booking_id: Mapped[int] = mapped_column(ForeignKey('bookings.id'))
time: Mapped[str]
user: Mapped['User'] = relationship('User', back_populates='times')
booking: Mapped['Booking'] = relationship('Booking', back_populates='list_times')
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(255))
surname: Mapped[str] = mapped_column(String(255))
profile_photo: Mapped[str] = mapped_column(String(255), default='default.jpg')
role: Mapped[str] = mapped_column(String(255), default='user')
email: Mapped[str] = mapped_column(String(255), unique=True)
personal_link: Mapped[str] = mapped_column(String(255), unique=True)
telegram_link: Mapped[str] = mapped_column(String(255), unique=True, default=None, nullable=True)
hashed_password: Mapped[str]
registered_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now(moscow_tz).replace(tzinfo=None))
is_active: Mapped[bool] = mapped_column(default=True)
description: Mapped[str | None] = mapped_column(String(500), default=None, nullable=True)
enabled: Mapped[bool] = mapped_column(default=True)
start_time: Mapped[time] = mapped_column(Time, default=time(7, 0))
end_time: Mapped[time] = mapped_column(Time, default=time(20, 0))
interval: Mapped[int] = mapped_column(default=30)
bookings: Mapped[list['Booking']] = relationship('Booking', back_populates='user')
times: Mapped[list['Times']] = relationship('Times', back_populates='user')
class Booking(Base):
__tablename__ = 'bookings'
id: Mapped[int] = mapped_column(primary_key=True)
date_for_booking: Mapped[date] = mapped_column(Date, nullable=True)
user_id: Mapped[int] = mapped_column(ForeignKey('users.id', ondelete='CASCADE'))
times: Mapped[list[str]] = mapped_column(JSON, nullable=True)
selected_times: Mapped[list[str]] = mapped_column(JSON, nullable=True, default=[])
user: Mapped['User'] = relationship('User', back_populates='bookings')
list_times: Mapped[list['Times']] = relationship('Times', back_populates='booking')
为了解决我遇到的问题,我尝试删除
Mapped
,以及关系中的
Model
The error message says that your
User
model is referencing the
Times
model before it has been defined. You need to define the
Times
model
before
the
User
model:
from sqlalchemy import ForeignKey, String, Integer, DateTime, Date, Time, JSON, Boolean
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime, time
from app.database import Base
from app.config import settings
from pytz import timezone
moscow_tz = timezone(settings.TIMEZONE)
class Times(Base):
__tablename__ = 'times'
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
booking_id: Mapped[int] = mapped_column(ForeignKey('bookings.id'))
time: Mapped[str]
user: Mapped["User"] = relationship('User', back_populates='times')
booking: Mapped["Booking"] = relationship('Booking', back_populates='list_times')
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(255))
surname: Mapped[str] = mapped_column(String(255))
# ... rest of your User model definition
bookings: Mapped[list["Booking"]] = relationship('Booking', back_populates='user')
times: Mapped[list["Times"]] = relationship('Times', back_populates='user')
class Booking(Base):
__tablename__ = 'bookings'
id: Mapped[int] = mapped_column(primary_key=True)
date_for_booking: Mapped[date] = mapped_column(Date, nullable=True)
# ... rest of your Booking model definition
user: Mapped["User"] = relationship('User', back_populates='bookings')
list_times: Mapped[list["Times"]] = relationship('Times', back_populates='booking')
This ensures that Python knows what
Times
refers to when it's used in the
User
model.
Additionally:
- Make sure you are importing all necessary modules correctly at the beginning of your models file.
- You might need to clear your SQLAlchemy metadata and recreate your tables if you have already run migrations with the incorrect model order.
By defining
Times
before
User
, SQLAlchemy should be able to correctly establish the relationship between them and resolve the error.