One contract. Two sources.
The desired structure and the introspected database are represented in the same normalized JSON format. A diff produces typed changes, which are translated into SQL for the selected database.
| Start from | How it reaches the engine |
|---|---|
| An Asqueel model | Projection of the physical schema |
| Human-readable JSON | JsonStructureProducer |
| XML | XmlStructureProducer |
| Your own model tooling | The normalized JSON contract |
The engine does not read your ORM model itself. The producer supplies the structure.
Plan, review, apply, verify
The service API separates planning from execution. It binds application of a plan to the identifier you reviewed.
from asqueel_migration import plan_migration, apply_migration
# database: a configured adapter; desired: normalized schema.
try:
plan = plan_migration(database, desired)
print(plan['sql'])
print(plan['warnings'])
# Run after reviewing the SQL and warnings:
result = apply_migration(
database, desired, expected_plan=plan['plan_id'],
)
print(result['verified'], result['remaining'])
finally:
database.closeConnection()
The identifier detects changes between review and execution. Unsupported changes block the reviewed apply operation. After execution, a fresh comparison reports whether differences remain.
Use it directly from Asqueel
With the migration extra installed, the Asqueel database object can project its model and call the engine.
plan = db.migration_plan() # Inspect without applying DDL.
db.migrate() # Apply, then compare again.
The CLI exposes the same workflow:
asqueel db plan ./console-demo
asqueel db apply ./console-demo
Follow the import and migration lesson →
Four dialects, explicit capabilities
| Database | Execution model | Important boundary |
|---|---|---|
| PostgreSQL | Transactional DDL for generated structural changes | Primary dialect; advanced database objects are not all modeled |
| SQLite | Transaction on the attached connection | No automatic table rebuild; foreign keys cannot cross attached files |
| MySQL | Best-effort DDL | Earlier statements may remain committed after a failure |
| SQL Server | Transaction for the DDL generated by the library | Capabilities and supported options differ from PostgreSQL |
These are the migration engine's dialects. The Asqueel query/runtime layer supports PostgreSQL and SQLite; MySQL and Microsoft SQL Server (MSSQL) are coming soon. Consult the Migration manual for operation-level coverage.
Additive by default
Success means the database can host the requested model without further additive changes. Extra objects remain. Table and column renames are not inferred.
Explicit removal support is limited to the implemented operations; it is not a general command to make every object identical. Type conversions and dependency changes require review.
An independent package
Install only the driver you need. SQLite uses Python's standard-library driver.
python -m pip install "asqueel-migration[postgresql,validation]"
The engine's base runtime dependency is dictdiffer. Driver and JSON Schema validation dependencies are extras.