Skip to main content

TUSKER Nuclei Fork

This fork implements a table exclusion feature into tusker.

[filter]

exclude_matches = ['a_table_to_exclude']

This will remove any SQL statements that contain any strings in the list from the generated diff output.

It also supports excluding whole schema files from the shadow databases that tusker builds to compute the diff:

[schema]

filename = "[!_]*.sql"
exclude_filename = ['huge_generated_file.sql']

Any file matching an exclude_filename glob is skipped when building the shadow schema. This is useful for large generated DDL (e.g. thousands of table partitions) whose objects are already suppressed from the diff via exclude_matches: there is no point paying to build them in the shadow database every run.

Tusker

PyPI

A PostgreSQL specific migration tool

Elevator pitch

Do you want to write your database schema directly as SQL which is understood by PostgreSQL?

Do you want to be able to make changes to this schema and generate the SQL which is required to migrate between the old and new schema version?

Tusker does exactly this.

Installation

pipx install tusker

Now you should be able to run tusker. Give it a try:

tusker --help

From source (with uv)

This project uses uv. To set up a development environment and run tusker from a checkout:

uv sync
uv run tusker --help

Getting started

Once tusker is installed create a new file called schema.sql:

CREATE TABLE fruit (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    name TEXT NOT NULL UNIQUE
);

You probably want to create an empty migrations directory, too:

mkdir migrations

Now you should be able to create your first migration:

tusker diff

The migration is printed to the console and all you need to do is copy and paste the output into a new file in the migrations directory. Alternatively you can also pipe the output of tusker diff into the target file:

tusker diff > migrations/0001_initial.sql

After that check that your schema.sql and your migrations are in sync:

tusker diff

This should give you an empty output. This means that there is no difference between applying the migrations in order and the target schema.

Alternatively you can run the check command:

tusker check

If you want to change the schema in the future simply change the schema.sql and run tusker diff to create the migration for you.

Give it a try and change the schema.sql:

CREATE TABLE fruit (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    name TEXT NOT NULL UNIQUE,
    color TEXT NOT NULL DEFAULT ''
);

Create a new migration:

tusker diff > migrations/0002_fruit_color.sql

Congratulations! You are now using SQL to write your migrations. You are no longer limited by a 3rd party data definition language or an object relational wrapper.

Configuration

In order to run tusker you do not need a configuration file. The following defaults are assumed:

  • The file containing your database schema is called schema.sql
  • The directory containing the migrations is called migrations
  • Your current user can connect to the database using a unix domain socket without a password.

You can also create a configuration file called tusker.toml. The default configuration looks like that:

[schema]
filename = "schema.sql"

[migrations]
filename = "migrations/*.sql"

[database]
#host = ""
#port = 5432
#user = ""
#password = ""
dbname = "my_awesome_db"
#schema = "public"

[migra]
safe = false
privileges = false

Instead of the exploded form of host, port, etc. it is also possible to pass a connection URL:

[schema]
filename = "schema.sql"

[migrations]
filename = "migrations/*.sql"

[database]
url = "postgresql:///my_awesome_db_connection"

You can also use an environment variable in place of a hard-coded value:

[database]
url = "${DATABASE_URL}"

How can I use the generated SQL files?

The resulting SQL files can either be applied to the database by hand or by using one of the many great tools and libraries which support applying SQL files in order.

Some recommendations are:

How does it work?

Upon startup tusker reads all files from the migrations directory and runs them on an empty database. Another empty database is created and the target schema is created. Then those two schemas are diffed using the excellent migra tool and the output printed to the console.

Tusker is unsafe by default

Unlike migra the tusker command by default does not throw an exception when a drop-statement is generated. Always check your generated migrations prior to running them. If you want the same behavior as migra you can either use the --safe argument or set the migra.safe configuration option to True in your tusker.toml file.

FAQ

Is it possible to split the schema into multiple files?

Yes. This feature has been added in 0.3. You can now use glob patterns as part of the schema.filename setting. e.g.:

[schema]
filename = "schema/*.sql"

As of 0.4.5 recursive glob patterns are supported as well:

[schema]
filename = "schema/**/*.sql"

Is it possible to diff the schema and/or migrations against an existing database?

Yes. This feature has been added in 0.2. You can pass a from and to argument to the tusker diff command. Check the output of tusker diff --help for more details.

How can I export initial schema from an existing database?

For exporting the initial schema you can use the native Postgres pg_dump command with the --schema-only option.

Tusker printed an error and left the temporary databases behind. How can I remove them?

Run tusker clean. This will remove all databases which were created by previous runs of tusker. Tusker only removes databases which are marked with a CREATED BY TUSKER comment.

What does the dbname setting in tusker.toml mean?

The dbname setting in tusker.toml specifies database name to be used when diffing against your database. This command will print out the difference between the current database schema and the target schema:

tusker diff database

Note that this command is meant to be run after you have migrated your database.

Tusker also needs to create temporary databases when diffing against the schema and/or migrations. The two databases are called {dbname}_{timestamp}_schema and {dbname}_{timestamp}_migrations.

The dbname setting overrides the database name in connection url (if specified). If neither a dbname nor a url is specified it will default to tusker. Calling tusker diff database only makes sense if you specify a dbname or your application does indeed use a database called tusker.

Metadata

Release files for tusker-nuclei 0.6.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tusker-nuclei 0.6.2
File Size Uploaded Provenance Actions
tusker_nuclei-0.6.2.tar.gz 39.6 kB Without provenance Details for tusker_nuclei-0.6.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tusker-nuclei 0.6.2
File Interpreter ABI Platform Actions
tusker_nuclei-0.6.2-py3-none-any.whl Python 3 none any Details for tusker_nuclei-0.6.2-py3-none-any.whl

Total release size: 50.6 kB

Release files / tusker_nuclei-0.6.2.tar.gz

Download URL tusker_nuclei-0.6.2.tar.gz
Size 39.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f219afee4f0dbb805ca598b2120055c62810cee14970ba897ea13a93ab004fcd
BLAKE2b-256 checksum
How to use checksums
921d0d1a578e9a40421b75922cdd79678342a4eaea1dc11e357e5cc8de203b04
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / tusker_nuclei-0.6.2-py3-none-any.whl

Download URL tusker_nuclei-0.6.2-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d1afd2a005232f16e0933c243488576bdd8e60929c5b8bb1d731e6453d793152
BLAKE2b-256 checksum
How to use checksums
084d4c2822ecb20c7047b6fe9670c96a87af3ce75ece47da7d02092c0ae5cec5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for tusker-nuclei 0.6.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.6.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page