Skip to content

Commit

Permalink
Merge pull request #14654 from opf/restore_project_script_ignore_conf…
Browse files Browse the repository at this point in the history
…licts

ignore conflicts when restoring a deleted project
  • Loading branch information
machisuji authored Jan 26, 2024
2 parents 515927e + 726981f commit 02cdc27
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ The following files will be used in the examples.

There is also a script ([restore.sh](./restore.sh)) that shows how to use everything together.

## 0. Prerequisites

* you have a Backup of your OpenProject installation with the missing data still present
* you have restored the database dump of this backup into a new, separate database called `openproject_backup`
* Created, for instance, via
* `psql -c 'create database openproject_backup'`
* `pg_restore -d openproject_backup openproject.pgdump`
* your present OpenProject database is called `openproject`

It does not matter where the actual Postgres server is running.
In all the following examples we simply use `psql -d openproject_backup` and `psql -d openproject` respectively. Where `openproject_backup` and `openproject` are the names of the databases within Postgres.

In your case you may have to provide more options (e.g. the user or host) to connect to the respective database.

## 1. Dump project data from backup

First we copy the data from the backup, that was deleted later.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ FOR source_table, source_column IN (
from information_schema.columns
where table_schema = 'public' and column_name = 'project_id'
and table_name not like '%_journals'
and table_name != 'grids'
-- apparently grids do not get deleted when a project is which is why we skip them here
-- otherwise there will be an 'already exists' error during restoration later
)
LOOP
EXECUTE 'CREATE TABLE missing_' || source_table || ' AS (' ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ BEGIN;
DO
$$
DECLARE table_to_copy TEXT;
DECLARE primary_keys TEXT;
DECLARE insert_sql TEXT;
BEGIN
FOR table_to_copy IN (
select table_name
Expand All @@ -16,8 +18,25 @@ FOR table_to_copy IN (
LOOP
raise notice 'Restoring % to %', table_to_copy, REPLACE(table_to_copy, 'missing_', '');

EXECUTE 'INSERT INTO ' || REPLACE(table_to_copy, 'missing_', '') ||
' (SELECT * FROM ' || table_to_copy || ');';
-- get primary keys for table
SELECT STRING_AGG(a.attname, ',') AS TEXT INTO primary_keys
FROM pg_index i
JOIN pg_attribute a
ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
WHERE i.indrelid = REPLACE(table_to_copy, 'missing_', '')::regclass
AND i.indisprimary;


insert_sql := 'INSERT INTO ' || REPLACE(table_to_copy, 'missing_', '') ||
' (SELECT * FROM ' || table_to_copy || ')';

-- do nothing on conflict if a primary key exists
IF primary_keys IS NOT NULL
THEN
insert_sql := (insert_sql || ' ON CONFLICT ('|| primary_keys ||') DO NOTHING');
END IF;

EXECUTE (insert_sql || ';');
END LOOP;
END;
$$;
Expand Down

0 comments on commit 02cdc27

Please sign in to comment.