PostgreSQL Love: deleting from views
I know that MySQL gets most of the attention in the relational-database field, as an easy-to-install, general-purpose relational database. But I've used PostgreSQL for years, and sometimes I have a moment like I did today that reminds me why.
In a quizzing application I run, I have an 'attempts' table with a lot of columns, and many of them are very wide. So, I created a view of the 'attempts' table that contains the key columns, and most of the time this view is what I use when I'm looking something up.
The problem is, you cannot delete records from a view (and rightly so). So, I often end up with a scenario like this:
# select * from attempts_brief where quiz=1479; id | quiz | person | score | out_of -------+------+--------+-------+---- 14981 | 1479 | admin | 20 | 20 14982 | 1479 | admin | | (2 rows)I want to delete those two dummy rows, so I alter the query, changing
SELECT * to DELETE, as I would on any other cautious deletion attempt. But I get this:
# delete from attempts_brief where quiz=1479; ERROR: cannot delete from a view HINT: You need an unconditional ON DELETE DO INSTEAD rule.Of course, the deletion fails, and I'm reminded that I'm not querying a table directly: silly programmer. But that hint, what a beaut! Using PostgreSQL's Rules system, I can tell the database what I really mean to do:
# create rule attempts_brief_del as on delete to attempts_brief # do instead delete from attempts where id=OLD.id; CREATE RULE
Now that the rule is in place, I can delete from the view, and the database will do the Right Thing:
# delete from attempts_brief where quiz=1479; DELETE 2
Perfect!
It's not a huge thing, I know. But it just reminds me how much time the Postgres designers spent, not only creating a system that is fast, consistent and powerful, but that is helpful, flexible and user-friendly to boot. I love ya, Postgres.
