On Sun, Jul 10, 2011 at 3:27 PM, Jim Dalton <jim.dal...@gmail.com> wrote:
> On Jul 10, 2011, at 3:13 AM, Simon Riggs wrote:
>
>> Maintaining the property of deferrable constraints seems important
>> here, so changing the deferrability of constraints, or overriding it
>> using the SET CONSTRAINTS command at the top of the transaction might
>> not be what we want.
>
> Well, that's just it. We want tests to behave as much like production code as 
> possible, so we actually *don't* want constraint checks to be deferred.
>
> When you're working with DB normally in production, i.e. outside of a 
> transaction, constraints are checked immediately. It's only when you get into 
> a transaction that they are deferred. Each of our tests run inside of a 
> transaction, which is an artificial construct. So to emulate production, I'm 
> arguing that this property is not something we want (*unless* we are testing 
> a transaction or transaction like behavior, in which case it does make sense 
> to temporarily suspend constraint checks).

My role here is to help with Postgres details, so any comments I make
are just attempts at providing useful information.

It sounds like there is a slight confusion about the way PostgreSQL
works. Everything is a transaction, so there is no difference between
inside/outside a transaction.

You can choose whether you wish immediate or deferred constraint
checking. It's completely user selectable, though the default is
immediate. If you're seeing deferred checks, they can be changed.

ISTM that the tests should work the same way as things do in
production, and it looks possible to make that happen.

>> What I would recommend is that we issue an explicit SET CONSTRAINTS
>> ALL IMMEDIATE command immediately before the ROLLBACK at *end* of
>> test. This will fire any outstanding checks. That way all constraint
>> checks will occur in the same place they would during a commit, yet we
>> can maintain the situation that the test ends with a rollback.
>
> This would conceivably work I think. I'm pretty sure Ramiro was exploring 
> this approach actually. My feeling, however, is that this still allows you to 
> get away with stuff you might not otherwise get away with in production. I 
> also think it's more helpful seeing exactly where an integrity issue came up 
> so you can address it. This is, for example, what allowed me to understand 
> the handful of bugs that were hiding, i.e. because I could trace the 
> Intergrity Error to the exact line of code that was triggering it.

It does seem sensible to make the tests work like production. Are we
sure they are different, given comments above?

> Your questions raise one issue that had not occurred to me though. One 
> possible "problem" with putting constraint checks at the beginning is that 
> there is now way for a test to recover from them. If you try to put bad data 
> into the DB with immediate constraint checks on, you will raise and error 
> *and* if I'm not mistaken the transaction will be rolled back at that very 
> instant. So if for some reason you knew you were putting bad data in and 
> wanted to recover from it in your test and keep going, that would not be 
> possible. I'm not sure that's actually a problem, but it's certainly 
> something to consider. It's another dimension of behavior that is changed.

If you want to recover from an error and then continue, you can use
SAVEPOINTs. These allow you to put a mark in the sand and return to it
in case of error.

e.g. in SQL

BEGIN;

INSERT  -- succeeds

SAVEPOINT s1

INSERT -- fails check

ROLLBACK to SAVEPOINT s1;

INSERT  -- succeeds

COMMIT;

I hope that info helps the decision process.

-- 
 Simon Riggs                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to