Migrations

sillyORM uses Alembic for migrations. It offers a few useful helpers that Monkeypatch some Alembic features for improved ease of use. You don’t have to use these helpers though, running standard Alembic and sillyORM with init_db_tables(automigrate=”none”) should work just fine!

Here’s an example for a simple script that uses sillyORM’s migration helpers:

import tempfile
import sillyorm
import os

class Example(sillyorm.model.Model):
    _name = "example"

    name = sillyorm.fields.String(length=255)

tmpdir = tempfile.TemporaryDirectory()
registry = sillyorm.Registry(f"sqlite:///{tmpdir.name}/db.sqlite3")
migration_dir = f"{tmpdir.name}/migrations"
os.mkdir(migration_dir)

registry.register_model(Example)
registry.resolve_tables()

# Demo that shows migrations must be applied first
try:
   registry.init_db_tables(automigrate="none")
except Exception as e:
   print(f"without migrations: {repr(e)}")
# Initialize migration helpers
sillyorm.migration_helpers.helper_init(
    registry, migration_dir
)
# Run migrations (they don't exist yet though)
sillyorm.migration_helpers.helper_do_migrate()
# This is NOT meant for prod, you should only
# automatically generate migrations in dev
#
# Also, this applies the migrations right away, you
# might want to have a look at them beforehand
# instead (done here just for illustrative purposes!)
#
# .. Maybe throw an exception if migrations are generated?
# And never generate & apply automatically in prod, just error if the
# schema doesn't match and the other migrations couldn't fix it!
if sillyorm.migration_helpers.helper_gen_migrations("autogenerated"):
    print("generated migrations")
    # Run the new migrations (do not do this, not even in dev!)
    sillyorm.migration_helpers.helper_do_migrate()

registry.init_db_tables(automigrate="none")

env = registry.get_environment(autocommit=True)

# Everything works as usual
record = env["example"].create({"name": "hello world!"})
print(f"name: {record.name}")
without migrations: SillyORMException("The DB does not match the schema and automigrate is set to 'none' - diffs: [('add_table', Table('example', MetaData(), Column('name', String(length=255), table=<example>), Column('id', Integer(), table=<example>, primary_key=True, nullable=False), schema=None))]")
generated migrations
name: hello world!