Flip PG_HECTIC_INHERITANCE default 0 -> 1. Set PG_HECTIC_INHERITANCE=0 to opt out.
7.1 KiB
db-tool
PostgreSQL development database management tool. Drop-in replacement for per-project database.sh / postgres-init.sh / postgres-cleanup.sh scripts. Provides database, postgres-init, and postgres-cleanup binaries.
Provided Binaries
| Binary | Description |
|---|---|
database |
Main script for managing migrations, deployments, and logs. |
postgres-init |
Ephemeral PostgreSQL cluster initialization and startup. |
postgres-cleanup |
Graceful shutdown and cleanup of the PostgreSQL cluster. |
Required Environment Variables
These variables must be set for db-tool to function.
| Variable | Description |
|---|---|
LOCAL_DIR |
Absolute path to the project root directory. |
DB_URL |
Full PostgreSQL connection string (e.g., postgresql://user@localhost/dbname?host=$PG_WORKING_DIR). |
PG_WORKING_DIR |
Directory where the PostgreSQL cluster data and sockets are stored. |
Optional Environment Variables
| Variable | Default Value | Description |
|---|---|---|
DATABASE_DIR |
${LOCAL_DIR}/db |
Root directory for database-related files. |
MIGRATION_DIR |
${DATABASE_DIR}/migration |
Directory containing SQL migration files. |
DATABASE_SOURCE |
${DATABASE_DIR}/src |
Directory containing source SQL files for hydration. |
PG_URL_VAR |
PGURL |
The name of the environment variable where the computed PG URL will be exported. |
PG_LOG_PATH |
(unset) | Path to redirect PostgreSQL server logs. |
PG_CONF_FILE |
(unset) | Path to a postgresql.conf file. When set, replaces the script-generated config entirely on fresh init. port and unix_socket_directories are still appended at runtime (always overridden). When set, PG_DISABLE_LOGGING and PG_SHARED_PRELOAD_LIBRARIES are ignored. |
PG_SHARED_PRELOAD_LIBRARIES |
pg_cron |
Comma-separated shared_preload_libraries value. Set to empty string to disable. Ignored when PG_CONF_FILE is set. |
PG_DISABLE_LOGGING |
0 |
Set to 1 to disable PostgreSQL logging collector. Ignored when PG_CONF_FILE is set. |
PG_HECTIC_INHERITANCE |
1 |
Apply the hectic inheritance bundle to the target database after init. Set to 0 to disable. |
HECTIC_INHERITANCE_SQL |
(auto) | Override path to the SQL file applied by PG_HECTIC_INHERITANCE=1. Defaults to the SQL shipped with postgres-init. |
PATCH_LOG |
(stdout) | Path to log the output of database patches. |
HYDRATE_LOG |
(stdout) | Path to log the output of database hydration. |
Postgres Package Override
By default, db-tool/postgres-init/postgres-cleanup use plain postgresql_17 from nixpkgs. If you need extensions (e.g. pg_cron), override the postgres package per-output:
let
myPg = pkgs.postgresql_17.withJIT.withPackages (_: [
pkgs.postgresql_17.pkgs.pg_cron
]);
in {
packages = [
(pkgs.hectic."db-tool".override { postgresql = myPg; })
(pkgs.hectic."postgres-init".override { postgresql = myPg; })
(pkgs.hectic."postgres-cleanup".override { postgresql = myPg; })
];
}
pull_staging Contract
The pull_staging subcommand allows importing data from a remote staging environment into the local test-data.sql file. This functionality requires four specific environment variables to be defined:
STAGING_SSH_HOST: The SSH destination for the staging server.STAGING_DB_URL: The PostgreSQL connection string for the remote staging database.STAGING_DUMP_TABLES: A space-separated list of tables to include in the data dump.STAGING_DUMP_FLAGS: Additional flags to pass topg_dump(e.g.,--column-inserts).
If any of these variables are missing when pull_staging is invoked, the tool will exit with code 3 and print the name of the missing variable to stderr.
Subcommands
deploy: Execute the full deployment flow (hydrate + patch). Supports--cleanupto teardown after success.log: Inspect database logs. Supportslistand index-based selection.test: Execute database tests located in${DATABASE_DIR}/test/test.sql.check: Run a deployment validation in an isolated, temporary PostgreSQL cluster.cleanup: Stop the local database cluster and remove thePG_WORKING_DIR.pull_staging: Import data from the staging environment based on the env contract.init: Wrapper aroundpostgres-initto start the cluster.migrator: Directly invoke the migration tool with the correct environment context.
shellHook Example
To use db-tool in a Nix development shell, add the following to your flake.nix or shell.nix:
{
# ...
devShells.default = pkgs.mkShell {
packages = [
pkgs.hectic.db-tool
pkgs.hectic.postgres-init
pkgs.hectic.postgres-cleanup
];
shellHook = ''
export LOCAL_DIR="$PWD"
export DATABASE_DIR="$LOCAL_DIR/db"
export MIGRATION_DIR="$DATABASE_DIR/migration"
export DATABASE_SOURCE="$DATABASE_DIR/src"
export PG_WORKING_DIR="$LOCAL_DIR/focus/postgresql"
export DB_URL="postgresql://user@localhost/dbname?host=$PG_WORKING_DIR&port=5432"
# for other non-db scripts (deploy.sh, task.sh, etc.):
export HECTIC_LIB="${pkgs.hectic.helpers.posix-shell.log}"
# Initialize and start the ephemeral database cluster
. ${pkgs.hectic.postgres-init}/bin/postgres-init
'';
};
}
hectic Inheritance Bundle
pkgs.hectic.hectic-inheritance ships a SQL artifact that bootstraps a hectic
schema with two parent tables and DDL event triggers:
hectic.created_at(created_at TIMESTAMPTZ NOT NULL DEFAULT NOW())— every user table mustINHERITS (hectic.created_at). The event triggerhectic_enforce_created_at_inheritanceraises an exception onCREATE TABLEotherwise.hectic.updated_at(updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW())— optional. Any table that inherits from it automatically gets aBEFORE UPDATE FOR EACH ROWtrigger callinghectic.set_updated_at()attached byhectic_attach_updated_at_trigger.
Always-exempt schemas: hectic, information_schema, anything matching
pg_*. Declarative partitions (relispartition = true) and temporary tables
are also auto-exempt.
Per-database opt-out for additional schemas via the
hectic.inheritance_extra_excluded_schemas GUC (comma-separated):
ALTER DATABASE mydb SET hectic.inheritance_extra_excluded_schemas = 'legacy,etl';
Apply via postgres-init
Applied automatically. Set PG_HECTIC_INHERITANCE=0 to opt out.
Apply via migrator or any psql pipeline
# in your devshell
shellHook = ''
export HECTIC_INHERITANCE_SQL=${pkgs.hectic.hectic-inheritance}/share/hectic/hectic-inheritance.sql
'';
psql "$DB_URL" -v ON_ERROR_STOP=1 -f "$HECTIC_INHERITANCE_SQL"
The SQL is also exposed via self.lib.hecticInheritance.sql (string) and
self.lib.hecticInheritance.path (Nix path) for inline pipelines.
Exit Codes
| Code | Meaning |
|---|---|
| 1 | Generic error. |
| 2 | Ambiguous arguments or state. |
| 3 | Missing required argument or environment variable. |
| 5 | Provided table does not exist. |
| 9 | Argument or command not found. |
| 13 | Program bug or unexpected system state. |
| 127 | Command not found (missing dependency). |