Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dmytro-demchyna/schema-keeper
:nut_and_bolt: Database development kit for PostgreSQL
https://github.com/dmytro-demchyna/schema-keeper
database-structure deployment plpgsql postgresql stored-procedures
Last synced: 3 months ago
JSON representation
:nut_and_bolt: Database development kit for PostgreSQL
- Host: GitHub
- URL: https://github.com/dmytro-demchyna/schema-keeper
- Owner: dmytro-demchyna
- License: mit
- Created: 2019-03-07T10:38:25.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-28T10:42:02.000Z (about 2 years ago)
- Last Synced: 2024-09-28T18:23:20.640Z (4 months ago)
- Topics: database-structure, deployment, plpgsql, postgresql, stored-procedures
- Language: PHP
- Homepage:
- Size: 159 KB
- Stars: 12
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
- jimsghstars - dmytro-demchyna/schema-keeper - :nut_and_bolt: Database development kit for PostgreSQL (PHP)
README
# SchemaKeeper
[![Latest Stable Version](https://img.shields.io/packagist/v/schema-keeper/schema-keeper.svg?color=blue)](https://packagist.org/packages/schema-keeper/schema-keeper)
[![Minimum PHP Version](https://img.shields.io/packagist/php-v/schema-keeper/schema-keeper.svg?color=blue)](https://php.net/)
[![Minimum PostgreSQL Version](https://img.shields.io/badge/postgreSQL-%3E%3D9.4-blue.svg)](https://www.postgresql.org/)
[![Build Status](https://img.shields.io/travis/com/dmytro-demchyna/schema-keeper/master.svg)](https://travis-ci.com/dmytro-demchyna/schema-keeper)
[![Coverage](https://img.shields.io/codecov/c/github/dmytro-demchyna/schema-keeper/master.svg)](https://codecov.io/gh/dmytro-demchyna/schema-keeper)
[![License](https://img.shields.io/github/license/dmytro-demchyna/schema-keeper.svg)](https://github.com/dmytro-demchyna/schema-keeper/blob/master/LICENSE)Track a structure of your PostgreSQL database in a VCS using SchemaKeeper.
SchemaKeeper provides 3 functions:
1. `save` — saves a database structure as separate text files to a specified directory
1. `verify` — detects changes between an actual database structure and the saved one
1. `deploy` — deploys stored procedures to a database from the saved structureSchemaKeeper allows to use `gitflow` principles for a database development. Each branch contains its own database structure dump, and when branches are merged, dumps are merged too.
## Table of contents
- [Installation](#installation)
- [Composer](#composer)
- [PHAR](#phar)
- [Docker](#docker)
- [Basic usage](#basic-usage)
- [save](#save)
- [verify](#verify)
- [deploy](#deploy)
- [Extended usage](#extended-usage)
- [PHPUnit](#phpunit)
- [Custom transaction block](#custom-transaction-block)
- [Workflow recommendations](#workflow-recommendations)
- [Safe deploy to a production](#safe-deploy-to-a-production)
- [Conflicts resolving](#conflicts-resolving)
- [Extra links](#extra-links)
- [Contributing](#contributing)## Installation
> If you choose the installation via Composer or PHAR, please, install [psql](https://www.postgresql.org/docs/current/app-psql.html) app on machines where SchemaKeeper will be used. A Docker build includes pre-installed [psql](https://www.postgresql.org/docs/current/app-psql.html).
### Composer
```bash
$ composer require schema-keeper/schema-keeper
```### PHAR
```bash
$ wget https://github.com/dmytro-demchyna/schema-keeper/releases/latest/download/schemakeeper.phar
```### Docker
```bash
$ docker pull dmytrodemchyna/schema-keeper
```## Basic Usage
Create a `config.php` file:
```php
setSkippedSchemas(['information_schema', 'pg_%']);// These extensions will be ignored
$params->setSkippedExtensions(['pgtap']);// The path to psql executable
$params->setExecutable('/bin/psql');return $params;
```Now you can use the `schemakeeper` binary. It returns exit-code `0` on success and exit-code `1` on failure.
### save
```bash
$ schemakeeper -c config.php -d /project_path/db_name save
```The command above saves a database structure to a `/project_path/db_name` directory.
- /project_path/db_name:
- structure:
- public:
- functions:
- func1(int8).sql
- materialized_views:
- mat_view1.txt
- sequences:
- sequence1.txt
- tables:
- table1.txt
- triggers:
- trigger1.sql
- types:
- type1.txt
- views:
- view1.txt
- schema2:
- views:
- view2.txt
- ...
- extensions:
- plpgsql.txtExamples of conversion database structure to files:
Object type | Schema | Name | Relative file path | File content
--------------------|----------------|------------------------------------------|------------------------------------|---------------
Table | public | table1 | ./public/tables/table1.txt | A description of the table structure obtained by `\d` [meta](https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-META-COMMANDS) command
Stored procedure | public | func1(param bigint) | ./public/functions/func1(int8).sql | A definition of the stored procedure, including a `CREATE OR REPLACE FUNCTION` block, obtained by [pg_get_functiondef](https://www.postgresql.org/docs/current/functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE)
View | schema2 | view2 | ./schema2/views/view2.txt | A description of the view structure obtained by `\d+` [meta](https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-META-COMMANDS) command
... | ... | ... | ... | ...The file path stores information about a type, a scheme and a name of a object. This approach makes an easier navigation through the database structure, as well as code review of changes in VCS.
### verify
```bash
$ schemakeeper -c config.php -d /project_path/db_name verify
```The command above compares an actual database structure with the previously saved in `/project_path/db_name` one and displays an information about changed objects.
If changes exists, the `verify` will returns an exit-code `1`.
An alternative way to find changes is to call the `save` again, specifying the same directory `/project_path/db_name`, and check changes in the VCS. Since objects from the database are stored in separate files, the VCS will show only changed objects. A main disadvantage of this way — a need to overwrite files.
### deploy
```bash
$ schemakeeper -c config.php -d /project_path/db_name deploy
```The command above deploys stored procedures from the `/project_path/db_name` to the actual database.
You can edit a source code of stored procedures in the same way as a rest of an application source code. Modification of a stored procedure occurs by making changes to the corresponding file in the `/project_path/db_name` directory, which is automatically reflected in the VCS.
For example, to create a new stored procedure in the `public` schema, just create a new file with a `.sql` extension in the `/project_path/db_name/structure/public/functions` directory, place a source code of the stored procedure into it, including a `CREATE OR REPLACE FUNCTION` block, then call the `deploy`. Similarly occur modifying or removal of stored procedures. Thus, the code simultaneously enters both the VCS and the database.
The `deploy` changes parameters of a function or a return type without additional actions, while with a classical approach it would be necessary to first perform `DROP FUNCTION`, and only then `CREATE OR REPLACE FUNCTION`.
Unfortunately, in some situations `deploy` is not able to automatically apply changes. For example, if you try to delete a trigger function, that is used by at least one trigger. Such situations must be solved manually using migration files.
The `deploy` transfers changes only from stored procedures. To transfer other changes, please, use migration files (for example, [doctrine/migrations](https://packagist.org/packages/doctrine/migrations)).
Migrations must be applied before the `deploy` to resolve possible problem situations.
> The `deploy` is designed to work with stored procedures written in [PL/pgSQL](https://www.postgresql.org/docs/current/plpgsql.html). Using with other languages may be less effective or impossible.
## Extended usage
You can inject SchemaKeeper to your own code.
```php
PDO::ERRMODE_EXCEPTION]);$params = new PSQLParameters($host, $port, $dbName, $user, $password);
$keeper = new Keeper($conn, $params);
``````php
saveDump('path_to_dump');
$keeper->verifyDump('path_to_dump');
$keeper->deployDump('path_to_dump');
```### PHPUnit
You can wrap `verifyDump` into a PHPUnit test:
```php
verifyDump('/path_to_dump');
} catch (\SchemaKeeper\Exception\NotEquals $e) {
$expectedFormatted = print_r($e->getExpected(), true);
$actualFormatted = print_r($e->getActual(), true);// assertEquals will show the detailed diff between the saved dump and actual database
self::assertEquals($expectedFormatted, $actualFormatted);
}
}
}```
### Custom transaction block
You can wrap `deployDump` into a custom transaction block:
```php
beginTransaction();try {
$result = $keeper->deployDump('/path_to_dump');
// $result->getDeleted() - these functions were deleted from the current database
// $result->getCreated() - these functions were created in the current database
// $result->getChanged() - these functions were changed in the current database$conn->commit();
} catch (\Exception $e) {
$conn->rollBack();
}
```## Workflow recommendations
### Safe deploy to a production
A dump of a database structure saved in a VCS allows you to check a production database for exact match to a required structure. This ensures that only intended changes were transferred to the production-DB by deploy.
Since the PostgreSQL [DDL](https://www.postgresql.org/docs/current/ddl.html) is [transactional](https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis), the following deployment order is recommended:
1. Start transaction
1. Apply all migrations in the transaction
1. In the same transaction, perform `deployDump`
1. Perform `verifyDump`. If there are no errors, execute `COMMIT`. If there are errors, execute `ROLLBACK`### Conflicts resolving
A possible conflict situation: *branch1* and *branch2* are branched from *develop*. They haven't conflict with *develop*, but have conflict with each other. A goal is to merge *branch1* and *branch2* into *develop*.First, merge *branch1* into *develop*, then merge *develop* into *branch2*, resolve conflicts in *branch2*, and then merge *branch2* into *develop*. At the stage of conflict resolution inside *branch2*, you may have to correct a migration file in *branch2* to match the final dump that contains merge results.
## Extra links
If you are not satisfied with SchemaKeeper, look at the list of another tools: https://wiki.postgresql.org/wiki/Change_management_tools_and_techniques
## Contributing
Any contributions are welcome.Please refer to [CONTRIBUTING.md](https://github.com/dmytro-demchyna/schema-keeper/blob/master/.github/CONTRIBUTING.md) for information on how to contribute to SchemaKeeper.