Alembic
Firing up the application with SQLModel models defined and imported will create initial tables, but as projects grow and refactoring takes place, managing databases needs handling with a migrations tool.
Install Alembic
Install Alembic:
And include it in the non_ver_reqs.txt
file:
Freeze the requirements:
Configure
First, run the init
command to initialize Alembic:
That will have created a new directory in the root of your project with a structure like this:
There are a few things to configure to make this compatible with SQLModel. Edit
env.py
and add the following imports:
You also need to import any schema you wish Alembic to manage. It might look like this isn't used but Alembic will pick up the schema for migrations, for example:
Additionally, update target_metadata
to use SQLModel.metadata
, for example:
Next, update alembic/script.py.mako
to include the following import:
And finally edit alembic.ini
and provide your database URL:
SQLite example:
Revision Init
With Alembic configured, time to create the initial migration:
That command creates the SQL ready to apply to the database under alembic/versions
.
To commit the changes, run:
Revisions
Moving forward with your project you can make changes to the database schemas in code, and use Alembic to make the changes to the database. Let's add a new column called teaser
, for example:
import uuid
from pydantic import AnyUrl
import datetime
from pydantic.types import UUID
from sqlmodel import SQLModel, Field
# Posts Schemas
class BlogPostIn(SQLModel):
title: str
teaser: str # NEW
content: str
cover_image: AnyUrl
published: bool
class Config:
json_schema_extra = {
"example": {
"title": "Lorem ipsum",
"teaser": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", # NEW
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"cover_image": "http://www.exampleforyou.net/static/img/excepteur_sint.jpg",
"published": True
}
}
class BlogPostOut(BlogPostIn):
id: uuid.UUID
created_date: datetime.datetime
# SQLModel Database Schemas
class BlogPost(BlogPostIn, table=True):
id: UUID | None = Field(
default_factory=uuid.uuid4,
primary_key=True,
index=True,
nullable=False)
created_date: datetime.datetime | None = Field(
default_factory=datetime.datetime.utcnow,
nullable=False)
Create a revision:
Examine the SQL that it will apply by looking at the new file under alembic/versions
, and apply them once again with:
To rollback and undo that change you can use:
Tip
There a many approaches to working with databases, in the case of SQLite and PostgreSQL you can use the command line as demonstrated here, alternatively you can use something like https://dbeaver.io/.
Working with SQLite
You can interact with SQLite via the command line, here's how you can do a quick validation of the table creation.
On Fedora, you can install sqlite3
natively with sudo dnf install sqlite
.
Open the database file:
To view the columns in a table:
To quit: