DBLiftClient
The synchronous Python API. Every CLI command has a client method that returns a result object instead of printing to a terminal.
Constructors
| Constructor | What it does |
|---|---|
from_sqlalchemy(engine) | Build a client from an existing SQLAlchemy engine. |
from_config(config) | Build from an in-memory config object. |
from_config_file(path) | Build from a config file on disk. |
migrate.py
from sqlalchemy import create_engine
from dblift.api import DBLiftClient
engine = create_engine("postgresql+psycopg://user:password@localhost:5432/mydb")
with DBLiftClient.from_sqlalchemy(engine, migrations_dir="migrations") as client:
client.validate()
client.migrate(dry_run=True, show_sql=True)
client.migrate()migrate()
Apply pending migrations. Returns a MigrateResult with details of applied migrations.
| Parameter | Default | Description |
|---|---|---|
target_version | None | Target version to migrate to |
dry_run | False | If True, don't actually apply migrations |
tags | None | Comma-separated tags to include |
exclude_tags | None | Comma-separated tags to skip |
versions | None | Specific versions to execute |
exclude_versions | None | Specific versions to skip |
placeholders | None | SQL placeholders for variable substitution |
mark_as_executed | False | Record migrations as applied without running them |
show_sql | False | Include migration SQL in outputs and reports |
show_query_results | False | Include rows returned by SELECT statements |
recursive | True | Search the scripts directory recursively |
There is no strict= argument. Strict missing-migration checks are config.strict_mode or the CLI --strict flag. Passing strict=True into migrate() raises TypeError.
info()
Read the schema history table and resolve it against the scripts on disk.
In 4.8.0, a connection that could not be opened, or a schema-history table that could not be created, raised ConnectionError. In 4.9.0, info() returns a failed InfoResult. Check result.success.
validate()
Compare every applied entry in the schema history table against the script that produced it. Checksums are checked by default. Missing applied files and strict version order are config.strict_mode or the CLI --strict flag. There is no strict= argument on validate(), the same as migrate().
validate() returns a failed ValidateResult when the connection cannot be opened or the schema-history table cannot be created (a reader role on an empty schema, for example). success is false, the message is the preflight text (Connection failed: ... or Could not create the schema-history table: ...), target_schema is set, and VALIDATION_FAILED is emitted. Nothing is raised and no warning is emitted for those two failures. Any other exception, including another ConnectionError, still propagates.
The CLI, including --format json, and the MCP validate tool still report both failures as ConnectionError (an MCP error result, not a validation verdict). JSON is {"success": false, "error": "ConnectionError: ..."}. On success, validate --format json sets error to null, not "".
A permission error shows the database's own message, not Connection failed: invalid credentials.
Connection and history-table failures
migrate(), undo(), baseline(), clean(), repair(), and import_flyway() follow the same rule as info() and validate(): those two preflight failures return a failed result of the method's own type. The message is the preflight text on its own. The CLI and dblift mcp still surface them as ConnectionError. AsyncClient runs the synchronous methods in a worker thread, so it returns the same failed results.
undo()
Run the undo script paired with each applied migration, newest first.
Other OSS methods
clean(), baseline(), repair(), import_flyway(), generate_undo_script() and generate_undo_scripts() exist on DBLiftClient. They match the CLI commands of the same name.
On a commercial install, diff(), export_schema(), snapshot(), plan() and preflight() are real methods. On OSS they exist as stubs that raise CapabilityDeniedError.
Context manager
close() releases DBLift resources. When the engine was supplied by you, it is left undisposed. Prefer with DBLiftClient.from_sqlalchemy(...) as client:.
See Python API — AsyncClient, SQLAlchemy, and Events & callbacks.