Skip to main content

SQLModel 学习

SQLModel is a library for interacting with SQL databases from Python code, with Python objects. It is designed to be intuitive, easy to use, highly compatible, and robust.

SQLModel is based on Python type annotations, and powered by Pydantic and SQLAlchemy.

key features

  • Intuitive to write: Great editor support. Completion everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.
  • Easy to use: It has sensible defaults and does a lot of work underneath to simplify the code you write.
  • Compatible: It is designed to be compatible with FastAPI, Pydantic, and SQLAlchemy.
  • Extensible: You have all the power of SQLAlchemy and Pydantic underneath.
  • Short: Minimize code duplication. A single type annotation does a lot of work. No need to duplicate models in SQLAlchemy and Pydantic.

Example

Database table

idnamesecret_nameage
1DeadpondDive Wilsonnull
2Spider-BoyPedro Parqueadornull
3Rusty-ManTommy Sharp48

Create a SQLModel Model

from typing import Optional

from sqlmodel import Field, SQLModel


class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
secret_name: str
age: Optional[int] = None

That class Hero is a SQLModel model, the equivalent of a SQL table in Python code.

And each of those class attributes is equivalent to each table column.

Create Rows

hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

This way, you can use conventional Python code with classes and instances that represent tables and rows, and that way communicate with the SQL database.

Write to the Database

# Create a SQLModel Model...

# Create Rows...

engine = create_engine("sqlite:///database.db") # 创建数据库连接引擎的方式

SQLModel.metadata.create_all(engine) # 自动搜索所有 SQLModel 类,并创建未被创建的 table

with Session(engine) as session:
# 加入 rows
session.add(hero_1)
session.add(hero_2)
session.add(hero_3)
# 提交修改
session.commit()

Select from the Database

# Create a SQLModel Model...

engine = create_engine("sqlite:///database.db")

with Session(engine) as session:
statement = select(Hero).where(Hero.name == "Spider-Boy")
hero = session.exec(statement).first()
print(hero)

Relationships-One-to-Many

Define Relationships Attributes

hero table

idnamesecret_nameageteam_id
1DeadpondDive Wilsonnull2
2Spider-BoyPedro Parqueadornull1
3Rusty-ManTommy Sharp481

team table

idnameheadquarters
1PreventersSharp Tower
2Z-ForceSister Margaret's Bar

Declare Relationship Attributes

Update table structure

from sqlmodel import Field, Session, SQLModel, create_engine


class Team(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
headquarters: str


class Hero(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
secret_name: str
age: int | None = Field(default=None, index=True)

# Add a field in
team_id: int | None = Field(default=None, foreign_key="team.id") table

# Code below omitted 👇

Add Relationship in two SQLModel

from sqlmodel import Field, Relationship, Session, SQLModel, create_engine


class Team(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
headquarters: str

# Add new relationship
heroes: list["Hero"] = Relationship(back_populates="team")


class Hero(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
secret_name: str
age: int | None = Field(default=None, index=True)

team_id: int | None = Field(default=None, foreign_key="team.id")
# Add new relationship
team: Team | None = Relationship(back_populates="heroes")

# Code below omitted 👇

Relationships-Many-to-Many

from sqlmodel import Field, Relationship, Session, SQLModel, create_engine


class HeroTeamLink(SQLModel, table=True):
team_id: int | None = Field(default=None, foreign_key="team.id", primary_key=True)
hero_id: int | None = Field(default=None, foreign_key="hero.id", primary_key=True)

# Code below omitted 👇

Team Model

# Code above omitted 👆

class Team(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
headquarters: str

heroes: list["Hero"] = Relationship(back_populates="teams", link_model=HeroTeamLink)

# Code below omitted 👇

Hero Model

# Code above omitted 👆

class Hero(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
secret_name: str
age: int | None = Field(default=None, index=True)

teams: list[Team] = Relationship(back_populates="heroes", link_model=HeroTeamLink)

# Code below omitted 👇

Resource