{"id":13464371,"url":"https://github.com/denismilovanov/PostgresqlDeployerGUI","last_synced_at":"2025-03-25T11:31:33.406Z","repository":{"id":21502299,"uuid":"24821273","full_name":"denismilovanov/PostgresqlDeployerGUI","owner":"denismilovanov","description":"GUI simplifies deployment of PostgreSQL schema (seeds, functions, types, sequences, triggers, tables partially) from your git repository","archived":false,"fork":false,"pushed_at":"2016-06-10T18:52:08.000Z","size":129,"stargazers_count":19,"open_issues_count":1,"forks_count":2,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-29T17:48:54.288Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/denismilovanov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-05T17:21:07.000Z","updated_at":"2023-08-27T05:19:37.000Z","dependencies_parsed_at":"2022-08-21T14:21:08.808Z","dependency_job_id":null,"html_url":"https://github.com/denismilovanov/PostgresqlDeployerGUI","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denismilovanov%2FPostgresqlDeployerGUI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denismilovanov%2FPostgresqlDeployerGUI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denismilovanov%2FPostgresqlDeployerGUI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denismilovanov%2FPostgresqlDeployerGUI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denismilovanov","download_url":"https://codeload.github.com/denismilovanov/PostgresqlDeployerGUI/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245453974,"owners_count":20617956,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T14:00:41.593Z","updated_at":"2025-03-25T11:31:32.981Z","avatar_url":"https://github.com/denismilovanov.png","language":"PHP","readme":"PostgresqlDeployerGUI\n=====================\n\n### Demo\n\n[http://pg.denismilovanov.net](http://pg.denismilovanov.net)\nE-mail `guest`, password `guest`.\n\n### Intro\n\nPostgresqlDeployerGUI provides you web interface that simplifies deployment of PostgreSQL schema.\nSingle database only, you can not deploy schema on two or more databases with sync commit.\n\nGenerally speaking there are several approaches to schema deployment.\n\nPopular approach is to use migrations. You take your favorite migration tool built in your framework,\nwrite 'up' code, write 'down' code, and you are done.\nAdvantages are obvious: one after you can deploy schema changes on any machine (local, staging, production) very easily.\n\nBut I see 2 problems here:\n\n1) migrations like `ALTER TABLE ADD COLUMN NOT NULL DEFAULT` on huge tables have to be performed manually in any case\n(fast `ALTER TABLE ADD COLUMN NULL` first, then `ALTER TABLE ALTER COLUMN SET DEFAULT`, then batch updates of null values),\n\n2) stored functions and types up and down migrations lead to great code overhead (to add one line in function you have to double\nits source code, to change function signature - to drop its previous version, to change type signature - to redeploy its depending functions).\n\nThat is why I don't believe in completely automatic migrations. They are suiteable only for small projects.\n\nGit (where I offer to store schema) is already migration-fashioned system. You may say `git checkout \u003ccommit_hash\u003e` and\nget schema state at any time in the past to rollback if it is needed, or say `git pull` and see the difference between states\n(if you organize database objects storage).\n\nPostgreSQLDeployerGUI works with 8 database objects types:\n* tables,\n* seeds (data of system dictionaries, mappings, settings, etc),\n* types (PostgreSQL user types),\n* functions (PostgreSQL stored procedures),\n* sequencies,\n* triggers,\n* views (limited support, actually you may only download definitions), \n* arbitrary queries.\n\nTables DDL's (`CREATE TABLE`, `CREATE INDEX`, `ALTER TABLE`) are committed into git and can be\ndeployed automatically if 2 conditions are satisfied:\n* there is no significant `deletions` lines in commit,\n* there are no cyclic table references in `additions` lines among commits.\n\nIf commit includes `deletions` it means that you have to apply corresponding changes by hands: system is not smart enough\nto produce 'revert' statements (`ALTER TABLE RENAME COLUMN`, `ALTER TABLE DROP COLUMN`, `DROP INDEX`, etc).\n\nIf commits include cyclic references system also requires you to do manual deployment even if statements can be ordered the way avoiding cycles.\n\nOther cases are marked as 'Can be forwarded #N', it means that statements can be deployed in automatic mode.\n\nSeeds are deployed automatically via `DELETE - INSERT`.\n\nTypes are deployed automatically by dropping old version of type with all dependent functions.\nInterface will show you dependencies, they will be included into deployment list.\n\nFunctions are deployed automatically by dropping old version if signature or return type were changed.\nThen `CREATE OR REPLACE FUNCTION` is called.\n\nAll changes are deployed in single transaction. You may exclude any object from list.\n\n### Installation\n\nClone repository:\n\n    git clone https://github.com/denismilovanov/PostgresqlDeployerGUI.git\n\nSetup dependencies via composer:\n\n    cd lib \u0026\u0026 composer update\n\nSetup your web server:\n\n    http://silex.sensiolabs.org/doc/web_servers.html\n\nRoute all queries to `htdocs/index.php`.\n\nOr use built-in php server:\n\n    php -S 0.0.0.0:8000 -t htdocs/\n\nPerform on your database(s) (psql):\n\n    \\i db.schema/create_schema.sql\n\nAdd new user (psql will show how).\n\nCreate databases config file:\n\n    nano lib/config/databases.json\n\nExample:\n\n    {\n        \"databases\": {\n            \"db1\": {\n                \"name\": \"DB 1\",\n                \"credentials\": {\n                    \"host\": \"localhost\",\n                    \"port\": \"5432\",\n                    \"user_name\": \"user1\",\n                    \"user_password\": \"pass1\",\n                    \"db_name\": \"db1\"\n                },\n                \"git_root\": \"/home/user/work/project/db1_git_root/\"\n\n                ,\"schemas_path\": \"dir1/dir2/schemas/\" #optinal, 'schemas/' by default\n\n                ,\"settings\": {\n                    #optional settings overloading global\n                    #see settings.json\n                }\n            },\n            \"db2\": {\n                \"name\": \"DB 2\",\n                \"credentials\": {\n                    \"host\": \"localhost\",\n                    \"port\": \"5432\",\n                    \"user_name\": \"user2\",\n                    \"user_password\": \"pass2\",\n                    \"db_name\": \"db2\"\n                },\n                \"git_root\": \"/home/user/work/project/db2_git_root/\"\n            }\n        }\n    }\n\nAll `git-root's` directories should be opened for write to user your server (FPM-workers for example) is running at, 'cause interface will\nperform write-commands such as `git checkout`.\n\nCreate settings file:\n\n    nano lib/config/settings.json\n\nExample:\n\n    {\n        \"settings\": {\n            \"not_in_git\": {\n                \"active\": true,\n                \"exclude_regexp\": \"(public\\\\.not_under_git_table)|(main\\\\.table_number_\\\\d+)\"\n            },\n            \"reload_and_apply\": {\n                \"active\": true,\n                \"ignore_manual\": false\n            },\n            \"plpgsql_check\": {\n                \"active\": false,\n                \"exclude_regexp\": \"tricky_functions_schema\\\\.tricky_\",\n                \"targets\": \"all\"\n            },\n            \"paths\": {\n                \"pg_bin\": \"/usr/lib/postgresql/%v/bin/\"\n            },\n            \"commits_list\": {\n                \"limit\": 10\n            },\n            \"interface\": {\n                \"sticky_control_buttons\": false\n            }\n        }\n    }\n\nAvailable settings:\n\n- not_in_git - this option tells if non-git database objects are shown (they will be marked as `NOT IN GIT`),\n- reload_and_apply - show 'Reload and apply' button (makes sense for development purposes only, not in production),\n- plpgsql_check - this option runs checking of all stored functions after deployment but before final commit (checking is performed by [plpgsql_check extension](https://github.com/okbob/plpgsql_check.git)\n  - active - use plpgsql_check or not. boolean, default false\n  - exclude_regexp - functions, that match this regexp, will be not checked\n  - targets - specify check functions: \"all\" for check all existing functions (default) or \"only_selected\" for check only functions for deploy\n- paths\n  - pg_bin - path to psql and pg_dump executables (%v will be replaced to MAJOR.MINOR version of current database you work at),\n- commits_list\n  - limit - max amount of commits to show,\n- interface - some interface features.\n\nYou may omit any of these options.\n\n### Repository\n\nYour schema repository should have structure like this:\n\n    repository_root/\n        schemas/\n            schema1/\n                functions/\n                    function_name1.sql\n                    function_name2.sql\n                    ...\n                seeds/\n                    seed_table_name1.sql\n                    seed_table_name2.sql\n                    ...\n                tables/\n                    table_name1.sql\n                    table_name2.sql\n                    ...\n                types/\n                    type_name1.sql\n                    type_name2.sql\n                    ...\n                sequences/\n                    sequence_name1.sql\n                    sequence_name2.sql\n                    ...\n                triggers/\n                    this_schema_table_name1.trigger_name1.sql\n                    this_schema_table_name2.trigger_name2.sql\n                    ...\n                queries_before/\n                    01_query.sql\n                    02_query.sql\n                    ...\n                queries_after/\n                    01_query.sql\n                    02_query.sql\n                    ...\n            schema2/\n                functions/\n                seeds/\n                tables/\n                types/\n                sequences/\n                triggers/\n                queries_before/\n                queries_after/\n            ...\n        other_directories/\n        ...\n\n### Seeds\n\nExpected structure of seed file `seed_table_name.sql`:\n\n    BEGIN;\n\n    DELETE FROM seed_table_name;\n\n    INSERT INTO seed_table_name (...)\n        VALUES (...);\n\n    COMMIT;\n\nPlease, do not use `TRUNCATE`, it is not MVCC safe.\n\nIf you use foreign key referenced to seed table you should make it `DERERRABLE INITIALLY DEFERRED`, in other case `DELETE FROM` will throw an error.\n\nThis structure allows you to deploy seed in manual mode with single transaction via simple copying the code.\n\n### Stored functions (procedures)\n\nExpected structure of function file `function_name.sql` (usual pg `CREATE OR REPLACE FUNCTION`):\n\n    CREATE OR REPLACE FUNCTION function_name(\n        \u003cparams\u003e\n    )\n        RETURNS ret_value_type AS\n    $BODY$\n    DECLARE\n    BEGIN\n        \u003cbody\u003e\n    END\n    $BODY$\n        LANGUAGE plpgsql;\n\n\nThese cases related to functions currently are not supported:\n\n1. Functions for functional indexes and handling triggers events are forbidden to be dropped automatically.\n2. Functions overloading. It is not allowed to have more than one functions with the same or different names in one file.\n\nWhen you use custom type name you should also provide schema name (even if schema is in `search_path`):\n\n    DECLARE\n        i_count integer;\n        r_element queues.t_queue_element;\n\n### Types\n\nExpected structure of type file `type_name.sql` (usual pg `CREATE TYPE`):\n\n    CREATE TYPE type_name AS (\n        \u003cdescription\u003e\n    );\n\n### Sequences\n\nExpected structure of sequence file `sequnces_name.sql`:\n\n    CREATE SEQUENCE sequence_name [\u003cparams\u003e];\n\n### Triggers\n\nTrigger file name should consist of table name and trigger_name (`table_name.trigger_name.sql`) and contain something like this:\n\n    CREATE TRIGGER trigger_name\n        AFTER INSERT ON current_schema_name.table_name\n        FOR EACH ROW\n        EXECUTE PROCEDURE arbitrary_schema.trigger_procedure();\n\nTrigger will be dropped and deployed again as soon as file content is changed (exactly like `seed` objects).\n\n### Notes\n\n1. Do not forget that `CREATE / DROP INDEX CONCURRENTLY` cannot be performed within a transaction block.\n\n","funding_links":[],"categories":["PHP"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenismilovanov%2FPostgresqlDeployerGUI","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenismilovanov%2FPostgresqlDeployerGUI","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenismilovanov%2FPostgresqlDeployerGUI/lists"}