I'm looking for a way to replicate a PostgreSQL schema to a database which may already have some of it defined. I wonder if there's a simple way to produce DDL that is idempotent (i.e. that can be applied any number of times) from PostgreSQL.
Currently I obtain DDL from my source DB using pgdump -s
, and manipulate it using the ad-hoc Python code below. I wonder if there's a cleaner solution.
import re
def MakeDdlIdempotent(sql):
"Make PGSQL DDL idempotent by changing various 'create' statements to idempotent versions"
ddlReplacements = {
"CREATE SCHEMA": "CREATE SCHEMA IF NOT EXISTS",
"CREATE TABLE": "CREATE TABLE IF NOT EXISTS",
"CREATE INDEX": "CREATE INDEX IF NOT EXISTS",
"CREATE VIEW": "CREATE OR REPLACE VIEW",
"CREATE FUNCTION": "CREATE OR REPLACE FUNCTION"
}
for orig, replacement in ddlReplacements.items():
sql = sql.replace(orig, replacement)
addConstraintRe = re.compile(r"ALTER TABLE [^;]+ ADD CONSTRAINT [^;]+;", flags = re.DOTALL | re.MULTILINE)
sql = addConstraintRe.sub(
r"""DO $$
BEGIN
BEGIN
\g<0>
EXCEPTION
WHEN invalid_table_definition OR duplicate_object OR duplicate_table THEN
END;
END $$;""",
sql)
return sql