Migrations#
🔥 Hot Tips
- Migrations are forward-rolling and track database changes using SQL statements.
- Use for incremental database updates during development.
- Tracked in the
tina4_migrationtable for status. - Migration files stored in
./migrationsand contain editable SQL.
Creating a Migration {#creating}#
Tina4 migrations are created by calling tina4 migrate:create. Provide a description for the migration.
uv run tina4 migrate:create "Create users table"- This generates a new migration file in
./migrationswith a timestamped name like000001_create_users_table.sql. - Description is normalized to lowercase with underscores.
- Edit the file to add your SQL code (e.g., CREATE TABLE, ALTER TABLE).
- Example SQL in the file:
CREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL );Migrations can also auto-generate SQL when initializing an ORM object if the table doesn't exist. It logs the CREATE TABLE SQL to the console, which you can copy into a migration file.
Running Migrations {#running}#
Run pending migrations via uv run tina4 migrate.
- Scans
./migrationsfor.sqlfiles, sorted alphabetically. - Executes SQL (split by
;) from unrun migrations. - Updates status in
tina4_migrationtable. - On failure, rolls back, logs error, and exits.
Migrations as Part of Startup {#startup}#
After declaring your database handle in code (e.g., app.py), call migrate to run migrations on startup.
from tina4_python.Database import Databasefrom tina4_python.Migration import migratedba = Database("sqlite3:test.db") # Example connectionmigrate(dba) # Runs all pending migrationsORM Integration {#orm}#
Define models extending tina4_python.ORM. Fields require type classes with optional parameters.
# src/app/models.pyfrom tina4_python import ORM, IntegerField, StringFieldclass Car(ORM): table_name = "car" # Optional, inferred as snake_case from class name id = IntegerField(primary_key=True, auto_increment=True) brand_name = StringField() year = IntegerField()- Initializing without table logs CREATE TABLE SQL.
- Fields map to snake_case in database.
- Supported field types include: IntegerField, StringField, TextField, DateField, etc. (import from
tina4_python.FieldTypes). - Parameters: primarykey, autoincrement, default_value, etc.
Database Configuration {#database-config}#
Configure connections directly in code or via environment variables for flexibility.
Example:
TINA4_DATABASE_URL=sqlite3:test.dbIn code:
import osfrom tina4_python.Database import Databasedba = Database(os.getenv("TINA4_DATABASE_URL", "sqlite3:test.db"))Supports SQLite, PostgreSQL, MySQL, MariaDB, MSSQL, Firebird. Install required drivers (e.g., uv add psycopg2 for PostgreSQL).