Postgresql - Determining what records are removed from a cascading delete

爱⌒轻易说出口 提交于 2021-02-08 04:01:37

问题


I have a fairly large postgreql database that I've inherited. We have a job that runs ~monthly that backs up the existing database and creates a new database with updated vendor data that we receive.

Currently there is a small issue with it. Without going into details of the table setup, what the data is modeling, etc, I believe it can be fixed with a simple delete query, as the tables are set-up to use cascading deletes.

However, it takes about 9 hours to generate this database from the vendor's provided source, so I'm always hesitant to introduce new changes. I currently have a copy of this database that I intend to run the query on first, to make user it 'CAN' run successfully. However, one of the downsides of sql in general is that when deletes are made, the output is typically something alone the lines of:

Query returned successfully: x rows affected, y ms execution time.

Is there a way in postgres to determine what rows were removed from which tables when using cascading deletes? I'd like to run the query on my copy and see if what is being dropped is what I expect, at least in what tables are being hit. Is this possible?


回答1:


Is there a way in postgres to determine what rows were removed from which tables when using cascading deletes?

Unfortunately no simple built-in way, but it's a great idea. Since cascading deletes are implemented under the hood by triggers, all you'd have to do is modify the referential integrity triggers so that cascade deletes raise a LOG level message with with the row information before deleting it. This would require changes to the PostgreSQL source code and a recompile.

Alternately, you can log all deletes by creating a new AFTER DELETE ... FOR EACH ROW trigger on each table referred to by a cascade constraint. It can be as simple as:

CREATE OR REPLACE FUNCTION log_delete() RETURNS trigger AS $$
BEGIN
    RAISE LOG 'Deleting row % (statement is %)', OLD, current_query();
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

That way you don't need to modify the DB, though you do need to install the trigger on every table that's subject to cascade deletes.

For bonus points you can even automate its creation by querying the information_schema for foreign key relationships, but it's probably more hassle than its worth.




回答2:


Another option. pg_dump before and after your query and then diff the SQL files.



来源:https://stackoverflow.com/questions/18452778/postgresql-determining-what-records-are-removed-from-a-cascading-delete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!