I've tried the following in two different projects, in one it works, in the other it doesnt. I'm gonna paste here all the relevant code for the one project is does not work:
src/
dependencies/
__init__.py
sqlmodel.py
models/
__init__.py
student.py
routes/
__init__.py
routes.py
students.py
main.py
main.py
from fastapi import FastAPI
from src.dependencies.sqlmodel import init_engine
def main():
init_engine()
main()
from src.routes.routes import api_router
app = FastAPI()
app.include_router(api_router)
dependencies/sqlmodel.py
import os
from sqlmodel import SQLModel, create_engine
root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
SQLITE_FILE_PATH = os.path.join(root, "database.db")
__engine = None
def init_engine():
global __engine
print(SQLITE_FILE_PATH)
__engine = create_engine(f"sqlite:///{SQLITE_FILE_PATH}", echo=True)
SQLModel.metadata.create_all(__engine)
def get_session() -> Generator[Session, None, None]:
with Session(__engine) as session:
yield session
SessionDep = Annotated[Session, Depends(get_session)]
models/student.py
from pydantic import BaseModel, Field
from sqlmodel import SQLModel
class StudentBase(SQLModel):
nombre: str
apellido: str
edad: int | None = Field(default=None, ge=17)
class Student(StudentBase, table=True):
identifier: int = Field(primary_key=True)
routes/routes.py
from fastapi import APIRouter
from src.routes import students
api_router = APIRouter()
api_router.include_router(students.router, prefix="/students", tags=["students"])
So when trying to run my fastapi application I get the mentioned error
ArgumentError: Mapper Mapper[Student(student)] could not assemble any primary key columns for mapped table 'student'
I have a very similar project, just with a different file structre, where all of this just works fine.
I've tried creating migrations with Alembic even, like this:
def upgrade() -> None:
op.create_table(
'student',
sa.Column('identifier', sa.Integer, primary_key=True),
sa.Column('name', sa.Text, nullable=False),
sa.Column('last_name', sa.Text, nullable=False),
sa.Column('age', sa.Integer)
)
But I get the same error (I made sure the path to the sqlite db is correct in all places)
In models/student.py
, you're importing Field
from pydantic
, it should be from sqlmodel
:
from sqlmodel import SQLModel, Field
class StudentBase(SQLModel):
nombre: str
apellido: str
edad: int | None = Field(default=None, ge=17)
class Student(StudentBase, table=True):
identifier: int = Field(primary_key=True)