Tools for deploying necessary schema changes for a perfactema database
Project description
PerFact DBSchemaTools
Tools for deploying necessary schema changes for a perfactema database.
It aims to gradually replace DatabaseModifications by a schema definition delivered in the form of yaml files in a file system structure, so we don't define the steps to perform to arrive at some required schema, but the target schema itself. It also allows introspecting the current database and checking which (additive) change are to be performed to arrive at the correct schema.
The maintainers of this project are:
- Alexander Rolfes alexander.rolfes@perfact.de
- Ján Jockusch jan.jockusch@perfact.de
- Viktor Dick viktor.dick@perfact.de
Technical details
The DBSchemaTools come bundled with an executable perfact-dbschema which is
available in /usr/bin. This allows several actions to be performed (check out
--help):
patch: Compare the current DB against the definitions provided in the schema definition paths and extend the current DB as required.add: Adds an entity to a schema definition pathdump: Dumps the full database into a schema definition path. Currently only for debugging.
Additionally, a wrapper perfact-dbschema-add is provided with a sudoers
file that allows the user zope to execute it as user perfact on a typical
PerFact system. This is intended to be used by the table manager while we
transition more and more functionality over.
On a PerFact template system, the package perfact-dbutils-zope4 additionally
provides a wrapper perfact-dbschema-patch. This is also used by the
zodbsync configuration to make sure that any code deployment runs through the
three steps:
- Check the schema definitions as recognized by perfact-dbschematools and execute them, before changing anything inside Zope.
- Play back
DatabaseModificationsand related paths, and trigger their application. - Play back any remaining code changes, i.e. the code that depends on the new schema.
A schema definition path is usually something like
/opt/perfact/dbutils-zoperepo/__schema__ or a similar path somewhere in
/var/lib/perfact/zodbsync/layers for an activated layer package. It contains
a folder structure mostly oriented along tables, containing YAML files (and in
the future probably also other file formats, when we include function
definitions) that describe the entities that we require to be present in the
database.
In preparation for a future situation where we can develop for multiple layers
on the same system, the main executable perfact-dbschema requires the path to
be explicitly named, making its arguments somewhat clumsy at times. Usually,
you should not have to interact with it directly, relying on the table manager
and on the wrapper perfact-dbschema-patch instead.
CLI Reference
The executable perfact-dbschema provides three subcommands. Use
perfact-dbschema --help or perfact-dbschema <subcommand> --help for
current usage details.
patch— Compare the schema definitions against the current database and apply all necessary changes.add— Add an entity (table, column, or view) to a schema definition path. Supports--return-patchto print the corresponding SQL without executing it.dump— Write the current database schema into a schema definition path. Intended for debugging or for retrieving the canonical form of expressions (e.g. after the firstpatchof a generated column).
YAML format
Schema definitions live in a directory structure rooted at the schema definition path.
Tables — tables/{table}/main.yml
Content is an empty YAML document (---). The mere existence of the file
registers the table.
Columns — tables/{table}/columns/{column}.yml
type: text # required — PostgreSQL column type
default: now() # optional — SQL default expression
Common type aliases are accepted and normalised (bigint → int8,
boolean → bool, integer → int4, etc.).
For default, Python scalars written directly in YAML are accepted and
normalised automatically:
| YAML | Stored as |
|---|---|
default: true |
true |
default: 42 |
42 |
default: 3.14 |
3.14 |
default: null |
removes any existing default |
default: "'some text'" |
'some text' (SQL string literal) |
If default is omitted entirely, any existing database default is
preserved.
Foreign keys — for columns following the naming convention
{src}_{tgt}_id:
type: int8
fk: cascade # one of: cascade, set null, restrict
Foreign key constraints are additive: once created they are never removed,
even if fk is later omitted from the YAML.
Generated columns (GENERATED ALWAYS AS):
type: int8
generated: "pdordlc_seqnum / 10"
generated and default are mutually exclusive. The expression must be
valid PostgreSQL. After the first patch, use dump to retrieve the
canonical (PostgreSQL-normalised) form of the expression and update the
YAML accordingly to avoid spurious change detection on subsequent runs.
Changing the expression of an existing generated column is not possible without dropping the column first — the tool will log a warning and skip the column if a mismatch is detected.
Views — views/{view}.yml or tables/{table}/views/{view}.yml
viewdef: "SELECT id, name FROM mytable WHERE active"
Views are recreated automatically when their definition changes. Dependency ordering between views is resolved automatically.
Usage from other packages
As of version 26.2.0, perfact-dbschematools no longer uses a virtual
environment and can therefore be imported in other Python packages. A package
that deploys some schema definitions that it requires to be executed to run can
therefore do something like this at startup:
from perfact.dbschematools import patch
patch('/path/to/my/schema/definition', my_connection_string)
Configuration
The default configuration file /etc/pefact/dbschematools/config.yml currently
only describes the database connection string.
FAQs
I tried deploying a code state that uses schema definitions and it failed
- Is
perfact-dbutils-zope4up to date? If you deployed using the layer packageperfact-zope-layers-complete, the dependency should be set correctly so the necessary versions are installed, but if you only deployed using agitcheckout, you will need to update the packages accordingly. - Does the configuration of
perfact-dbschematoolscontain the correct connection string? - If you skipped the failures and continued the deployment, but fixed the
cause, you can execute
perfact-dbschema-patchto retry. - Afterwards, you want to retry applying the
DatabaseModifications.
During development, a column I created should have a different type after all
- Edit the file in
__schema__/tables/<table>/columns/<column>.yml - Execute
perfact-dbschema-patch. - If the column can not be converted automatically due to completely different types, you will need to first delete the column manually.
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 perfact_dbschematools-26.7.0.tar.gz.
File metadata
- Download URL: perfact_dbschematools-26.7.0.tar.gz
- Upload date:
- Size: 29.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5cf550342ff78b2a41db2ca30fe4ef198066542d4f85ea0219005bc030d1f0c
|
|
| MD5 |
b13c7fb4f915c8f6557c17159ae52357
|
|
| BLAKE2b-256 |
bd04cb7880c2b3946ac3dfd66eb907a6d5c984d920028a8903eea6253b0f022e
|
File details
Details for the file perfact_dbschematools-26.7.0-py2.py3-none-any.whl.
File metadata
- Download URL: perfact_dbschematools-26.7.0-py2.py3-none-any.whl
- Upload date:
- Size: 30.5 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cd6d50c181a4ff9673f2ffe1a0a86d9f3bfc328ef918e653bd8d270c5804c20
|
|
| MD5 |
124907a499fb4bfa14daf8f203fb1e81
|
|
| BLAKE2b-256 |
c0e780bc52c081b3040cd90d5c391f0c70ce53993e01abeacc267fe312e112b0
|