A simple migration tool for DuckDB databases.
Project description
quackup
quackup is a simple and powerful migration tool for duckdb databases, designed with a clean and familiar CLI interface. Inspired by tools like alembic and flyway, quackup helps manage your database schema changes with up/down migrations, versioning, and safe rollbacks.
Key features
- Versioned migrations: Automatically generate timestamped migrations containing raw duckdb-compatible SQL statements.
- Up & down migrations: Apply and rollback migrations easily using the CLI.
- Configurable migrations directory: Specify a custom directory for migrations if you need to use quackup alongside other migration tools in the same project.
- Dry-run mode: Preview what migrations will run without applying any changes using the
--dry-runoption. - Flexible rollbacks: Rollback a specific number of the latest applied migrations using the
--countoption. - Migration status: View which migrations are applied or pending.
- Supports .env Files: Easily specify the path to your duckdb database using environment variables.
Installation
quackup is available on pypi and can be installed using pip:
pip install quackup
Contents
- Project structure
- Initilization
- Configuration
- Creating migrations
- Applying migrations
- Rolling back migrations
- Listing migration status
Project structure
Below is a depiction of the files contained in a typical python project using quackup. The migrations directory may be named differently if configured with a custom name.
.
├─ migrations/
│ ├─ 2025_02_25_1450-00123abc_create_users_table/
│ │ ├─ up.sql
│ │ └─ down.sql
│ └─ 2025_02_25_1500-00456def_add_email_to_users/
│ ├─ up.sql
│ └─ down.sql
├─ quackup.ini
└─ .env (optional)
Usage
1. Initialize quackup
Before you can use quackup in your project, you need to initialize it. This creates configuration files necessary for it to work.
quackup init
This will create a quackup.ini configuration file and a migrations directory (if they don't already exist):
.
├─ quackup.ini # Configuration file for quackup
└─ migrations/ # Directory for storing migration files
To specify a custom migrations directory, use the --migrations-dir option:
quackup init --migrations-dir custom_migrations
2. Configure quackup
After running quackup init, the quackup.ini file will contain:
[quackup]
db_env_var = DUCKDB_PATH
migrations_dir = migrations
You can then set the path to your duckdb database using a .env file. The name of the environment variable must match the value you set db_env_var to in your quackup.ini file.
# .env file
DUCKDB_PATH=/path/to/your_database.duckdb
When deploying your migrations into a staging or production environment for example, you'll want to set this variable's value in the system's environment (or a Docker image).
3. Create a new migration
quackup create "Add email to users table"
This will generate a timestamped migration folder inside the
configured migrations directory with up.sql and down.sql files:
migrations/
└─ 2025_02_25_1500-00456def_add_email_to_users/
├─ up.sql
└─ down.sql
Place the SQL statements you want to run during a migration in the
up.sql file, and corresponding SQL statements you want to undo those
changes in the down.sql file in the same folder.
Transaction support
The generated up.sql and down.sql files are automatically wrapped in a duckdb transaction, ensuring atomicity:
BEGIN TRANSACTION;
-- Your migration logic here
-- Example: ALTER TABLE users ADD COLUMN age INTEGER;
COMMIT;
This prevents partial application of migrations and helps maintain database integrity.
4. Apply all pending migrations
quackup up
If you specified a custom migrations directory during initialization, quackup will automatically use it.
You can also dry-run to see which migrations would be applied:
quackup up --dry-run
5. Rollback migrations
To rollback the latest migration (default behavior):
quackup down
To rollback a specific number of recent migrations, use the --count option:
quackup down --count 3
The above example would rollback the three most recently applied migrations.
You can also preview the rollback actions without applying changes using the dry-run mode:
quackup down --count 2 --dry-run
The above example would show the contents of the most recent two migrations that would be rolled back, but will not actually apply them.
6. Check migration status
quackup status
Example Output:
Migration Status
-------------------------------------------------------
2025_02_25_1450-00123abc_create_users_table up
2025_02_25_1500-00456def_add_email_to_users down
If a custom migrations directory is configured, this command will automatically reflect that.
⚠️ Important considerations
- Always test migrations in a staging environment before applying them in production to prevent accidental data loss.
- When rolling back migrations, use the
--countoption to precisely control how many migrations are undone. - The dry-run mode is a great way to verify what quackup will execute before applying changes.
Contributing
Contributions are welcome! If you find bugs, have feature requests, or want to contribute, please open an issue or submit a pull request.
Testing contributions
To run tests in your own fork:
-
Create a virtual environment in the
.venvdirectory.py -m pip install virtualenv py -m virtualenv .venv
-
Enter the virtual environment.
Run the appropriate activate script depending on your shell.
Examples:
- Bash:
source ./.venv/scripts/activate.sh
- Windows PowerShell:
.\.venv\Scripts\Activate
- Bash:
-
Install test dependencies with
pip install -e .[test] -
Run tests with
pytest -v
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quackup-0.2.1.tar.gz.
File metadata
- Download URL: quackup-0.2.1.tar.gz
- Upload date:
- Size: 13.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be94bc4c7e34ae8e1c503bf77446fdbc8bc4c8c7591ac65cc8ef3941e65e4126
|
|
| MD5 |
468668c1d194b51ad71be23ba8743f45
|
|
| BLAKE2b-256 |
a67ced9c127dc233a886785ac9b8bf24adfbd4f1d62fe4fada663ddaf01305ed
|
File details
Details for the file quackup-0.2.1-py3-none-any.whl.
File metadata
- Download URL: quackup-0.2.1-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85e9cd2cd0d7e18836b9e07279dfd9e7e095572aacfbccec17f5bd22847ac3a3
|
|
| MD5 |
bcf302956f36f3a6bcd51bada25d9127
|
|
| BLAKE2b-256 |
2559cff5274124bbe6bf7187d099c3672aec44deb48608425de891b407c0c253
|