Two ways to fix it: one wrong, and one correct.
The wrong way to fix it is to use a before
trigger. I say wrong because, simply put, side effects on other tables belong in an after
trigger like you did. This not just in theory: side effects to expect at some point or another include incorrect counts reported by psql
, wrong aggregate values because your row doesn't exist in a table yet (or its old value does, in case of updates or deletes), the list of quirks goes on and on ad nausea.
The correct way is to fix it is to make your foreign key deferrable:
http://www.postgresql.org/docs/current/static/sql-createtable.html
FOREIGN KEY ( column_name [, ... ] )
REFERENCES reftable [ ( refcolumn [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE action ] [ ON UPDATE action ]
[ DEFERRABLE | NOT DEFERRABLE ]
[ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
You probably want deferrable initially deferred
.