Closed medihack closed 2 weeks ago
Trying to understand how it ends up with duplicate objects. I would imagine that doing the setup involves starting from a fresh DB, and as long as it doesn't do back-and-forth with migrations, then there's no reason it would do that.
But if it either doesn't start from a fresh DB or if the process involves applying and unapplying a migration, then of course, given our migrations don't include a reverse SQL, it's going to be problematic at some point. If that's the case, I believe it should be possible that RunProcrastinateSQL
would be able to offer automated reverse SQL using migra
.
I think it's not a problem with reverse migrations as they only use forward migrations. I guess it's more a problem that they only drop all model tables and don't respect anything that may be created by some custom SQL code. So I guess we can't do anything about it, but I have to just use that ugly workaround I mentioned.
Just in case anyone in the future is having that problem, another way to drop everything that is prefixed with procrastinate_
:
with connection.cursor() as cursor:
cursor.execute("""
DO $$
DECLARE
prefix text := 'procrastinate_';
rec record;
BEGIN
-- Drop tables
FOR rec IN
SELECT tablename
FROM pg_tables
WHERE tablename LIKE prefix || '%'
LOOP
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(rec.tablename) || ' CASCADE';
END LOOP;
-- Drop functions
FOR rec IN
SELECT n.nspname as schema_name,
p.proname as func_name,
pg_catalog.pg_get_function_identity_arguments(p.oid) as args
FROM pg_proc p
LEFT JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE p.proname LIKE prefix || '%'
LOOP
EXECUTE 'DROP FUNCTION IF EXISTS ' || quote_ident(rec.schema_name) || '.'
|| quote_ident(rec.func_name) || '(' || rec.args || ') CASCADE';
END LOOP;
-- Drop types
FOR rec IN
SELECT typname
FROM pg_type
WHERE typname LIKE prefix || '%'
LOOP
EXECUTE 'DROP TYPE IF EXISTS ' || quote_ident(rec.typname) || ' CASCADE';
END LOOP;
END $$;
""")
While integrating Procrastinate into our applications, we found that Procrastinate doesn't play well together with django-test-migrations (see error below). I don't blame that this is the fault of Procrastinate, but it is more I guess how django-test-migrations cleans the database.
This is what happens when running a test ...
One workaround I found is to drop all the Procrastinate stuff manually
This is, of course, rather ugly (is there a more easy way?).
I wonder if it would make sense to always use
CREATE OR REPLACE
(even in the00.00.00_01_initial.sql
migration). That way, the duplication error will be avoided.I totally understand if we don't do anything and just say it's the fault of django-test-migrations, especially as there is a similar open issue in the repo of django-test-migration).