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
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:sql
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
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
After declaring your database handle in code (e.g., app.py), call migrate to run migrations on startup.
from tina4_python.Database import Database
from tina4_python.Migration import migrate
dba = Database("sqlite3:test.db") # Example connection
migrate(dba) # Runs all pending migrationsORM Integration
Define models extending tina4_python.ORM. Fields require type classes with optional parameters.
# src/app/models.py
from tina4_python import ORM
from tina4_python.FieldTypes import IntegerField, StringField
class 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: primary_key, auto_increment, default_value, etc.
Database Configuration
Configure connections directly in code or via environment variables for flexibility.
Example:
TINA4_DATABASE_NAME=sqlite3:test.dbIn code:
import os
from tina4_python.Database import Database
dba = Database(os.getenv("TINA4_DATABASE_NAME", "sqlite3:test.db"))Supports SQLite, PostgreSQL, MySQL, MariaDB, MSSQL, Firebird. Install required drivers (e.g., uv add psycopg2 for PostgreSQL).