Issues with initializing mappers and relationships across multiple files with SQLModel #1247
Unanswered
reinaldosaraiva
asked this question in
Questions
Replies: 1 comment
-
No sure about it, but my issue can be related: #1248 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
First Check
Commit to Help
Example Code
Description
Description:
I'm experiencing persistent issues when using SQLModel with relationships between models defined in separate files. My setup involves FastAPI, SQLModel (0.0.22), and SQLAlchemy with Python 3.12.8. While isolated unit tests for creating a single CNESFile model work fine, the full application integration frequently fails at startup due to mapper initialization errors.
Errors Observed:
Common error messages:
When initializing mapper Mapper[HealthUnit(cnes_health_unit)], expression 'Address' failed to locate a name ('Address') ...
When initializing mapper Mapper[Address(cnes_address)], expression "relationship("List['HealthUnit']")" ...
TypeError: issubclass() arg 1 must be a class
These occur even after attempting changes suggested in various GitHub issues and StackOverflow answers:
Adding from future import annotations
Using Mapped[List["HealthUnit"]] = relationship(...)
Consolidating models into a single file (changes error messages but doesn't fully resolve the problem).
Interestingly, my isolated unit tests (which create and persist a CNESFile model) run successfully. The errors appear when the entire application, including all routers and models, is loaded at runtime.
Environment:
Python 3.12.8
SQLModel 0.0.22
FastAPI 0.115.6
macOS
Running under poetry-managed virtual environment
Directory Structure:
bash
Copiar código
core
├── cnes
│ ├── address
│ │ └── models.py # Contains Address model
│ ├── cnes_file
│ │ └── models.py # Contains CNESFile model
│ ├── health_unit
│ │ └── models.py # Contains HealthUnit model
│ ├── team
│ │ └── models.py # Contains Team model
│ └── routers
│ └── cnes.py
└── main.py
Example Models (Simplified):
python
Copiar código
core/cnes/address/models.py
from future import annotations
from typing import List, Optional
from datetime import datetime
from sqlmodel import Field, Relationship, SQLModel
from core.contrib.models import BaseModelMixin
class Address(BaseModelMixin, table=True):
tablename = "cnes_address"
id: int = Field(primary_key=True, index=True)
replicate: int
type_id: str
street_id: int
neighborhood_id: int
municipality_id: int
state_code: str = Field(max_length=2)
country_id: int
number: Optional[str] = Field(default=None, max_length=20)
complement: Optional[str] = Field(default=None, max_length=20)
zip_code: Optional[int]
latitude: Optional[float]
longitude: Optional[float]
active: Optional[bool]
python
Copiar código
core/cnes/cnes_file/models.py
from future import annotations
from typing import List
from datetime import datetime
from sqlmodel import Field, Relationship, SQLModel
from core.contrib.models import BaseModelMixin
class CNESFile(BaseModelMixin, table=True):
tablename = "cnes_file"
id: int = Field(primary_key=True, index=True)
file_name: str = Field(..., max_length=255)
import_date: datetime
import_count: int = Field(default=0)
version_file: str = Field(..., max_length=20)
python
Copiar código
core/cnes/health_unit/models.py
from future import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy import UniqueConstraint
from sqlmodel import Field, Relationship, SQLModel
from core.contrib.models import BaseModelMixin
class HealthUnit(BaseModelMixin, table=True):
tablename = "cnes_health_unit"
table_args = (UniqueConstraint("cnes_code", name="uq_cnes_health_unit_cnes_code"),)
python
Copiar código
core/cnes/team/models.py
from future import annotations
from datetime import datetime
from typing import Optional
from sqlmodel import Field, Relationship, SQLModel
from core.contrib.models import BaseModelMixin
class Team(BaseModelMixin, table=True):
tablename = "cnes_team"
id: int = Field(primary_key=True, index=True)
replicate: int
ibge_municipality: str = Field(..., max_length=6)
area_code: str = Field(..., max_length=4)
team_sequence: int
area_description: str
health_unit_id: int = Field(foreign_key="cnes_health_unit.id")
team_type_code: str
reference_name: str
team_type: bool
segment_code: str
assist_quilombola: bool
assist_settled: bool
assist_general: bool
assist_school: bool
assist_pronasci: bool
activation_date: datetime
inactivation_date: datetime
inactivation_type: bool
inactivation_reason_code: str
ine: str
active: bool
cnes_file_id: Optional[int] = Field(default=None, foreign_key="cnes_file.id")
What I've Tried:
Ensuring all models inherit from the same SQLModel base.
Using future import annotations.
Attempting to annotate relationships as recommended by SQLAlchemy 2.0-style mappings.
Consolidating models into one file (which just changes the error type).
Running tests: unit tests for CNESFile creation and retrieval succeed, but the full app load fails.
Questions:
Are there known issues or best practices for SQLModel with multiple files and relationships?
Is there a recommended way to ensure that all models and relationships are fully resolved before the application starts?
Could this be related to Python 3.12.8 or SQLAlchemy/SQLModel versions?
Any guidance, insights, or examples on how to structure these models so that relationships can be resolved without errors would be greatly appreciated. Thank you!
Operating System
macOS
Operating System Details
MacOS Sequoia 15.0
SQLModel Version
0.0.22
Python Version
3.12.8
Additional Context
❯ pip show fastapi
Name: fastapi
Version: 0.115.6
Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production
Home-page:
Author:
Author-email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= [email protected]
License:
Location: /Users/reinaldosaraiva/Library/Caches/pypoetry/virtualenvs/core-dIBwzXsG-py3.12/lib/python3.12/site-packages
Requires: pydantic, starlette, typing-extensions
Required-by:
❯ pip show sqlmodel
Name: sqlmodel
Version: 0.0.22
Summary: SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.
Home-page:
Author:
Author-email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= [email protected]
License:
Location: /Users/reinaldosaraiva/Library/Caches/pypoetry/virtualenvs/core-dIBwzXsG-py3.12/lib/python3.12/site-packages
Requires: pydantic, SQLAlchemy
Required-by:
❯ python --version
Python 3.12.8
Beta Was this translation helpful? Give feedback.
All reactions