Search Postgresql Archives

Re: What have I done!?!?!? :-)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/8/22 09:27, Magnus Hagander wrote:


On Fri, Apr 8, 2022 at 3:23 PM Perry Smith <pedz@xxxxxxxxxxxxxxxx <mailto:pedz@xxxxxxxxxxxxxxxx>> wrote:
    It has been a long time since I’ve done Rails stuff.  What follows
    is the best I can recall but please take it with a grain of salt.

    The first problem is that generally Rails does not put constraints
    in the database.  There were others like me who thought that was
    insane and would put constraints in the database — this includes
    foreign key constraints, check constraints, etc.  About the only
    constraint that could be added into the DB using native Rails was
    the “not null” constraint.

    When foreign and other constraints were added, it broke something
    they call “Fixtures” which are present db states that are plopped
    into the DB during testing.  To “fix” that, I (and others) would add
    this into our code base: (I’m adding this to see what you guys think
    of it — is it safer / better or just as insane?)

           def disable_referential_integrity(&block)
             transaction {
               begin
                 execute "SET CONSTRAINTS ALL DEFERRED"
                 yield
               ensure
                 execute "SET CONSTRAINTS ALL IMMEDIATE"
               end
             }
           end


This is perfectly normal code and nothing wrong with it. DEFERRED constraints are how you are *supposed* to handle such things. It defers the check of the foreign key to the end of the transaction, but it will still fail to commit if the foreign key is broken *at that point*. But it lets you do things like modify multiple tables that refer to each other, and have the changes only checked when they're all done.

Indeed, especially because this code does not require any elevated permissions, guarantees referential integrity at commit time and guarantees that no inconsistent, intermediate state will ever be visible to another, concurrent session.

It only affects constraints that have been declared DEFERRABLE. Those that are not are silently ignored (as per SQL standard).

A lot of frameworks didn't support foreign keys because one of the most popular databases at that time didn't support them. Well, the SQL parser of that particular database would accept the syntax, but the engine would not enforce anything. Even the manual of that database stated that "foreign keys are mostly for documentation purposes and are not needed as long as the application does all operations in the correct order." They changed that part of the documentation when support for InnoDB was added. Therefore I would not put all blame on the Rails developers.


Best Regards, Jan





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]

  Powered by Linux