Ticket #11665: 11665.2.diff

File 11665.2.diff, 5.0 KB (added by Ramiro Morales, 13 years ago)

Better patch (use addError() instead of reraising exceptions in _fixture_teardown()) + workaround for one of the failing multiple_database tests it introduces

  • django/db/backends/__init__.py

    diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
    a b  
    255255    def make_debug_cursor(self, cursor):
    256256        return util.CursorDebugWrapper(cursor, self)
    257257
     258    def check_constraints(self):
     259        sql = self.ops.check_constraints_sql()
     260        for s in sql:
     261            self.cursor().execute(s)
     262
    258263class BaseDatabaseFeatures(object):
    259264    allows_group_by_pk = False
    260265    # True if django.db.backend.utils.typecast_timestamp is used on values
     
    440445        """
    441446        return ''
    442447
     448    def check_constraints_sql(self):
     449        """
     450        Returns the SQL necessary to force deferred constraints to be checked.
     451        """
     452        return []
     453
    443454    def drop_foreignkey_sql(self):
    444455        """
    445456        Returns the SQL command that drops a foreign key.
  • django/db/backends/postgresql_psycopg2/operations.py

    diff --git a/django/db/backends/postgresql_psycopg2/operations.py b/django/db/backends/postgresql_psycopg2/operations.py
    a b  
    3939    def deferrable_sql(self):
    4040        return " DEFERRABLE INITIALLY DEFERRED"
    4141
     42    def check_constraints_sql(self):
     43        return ["SET CONSTRAINTS ALL IMMEDIATE"]
     44
    4245    def lookup_cast(self, lookup_type):
    4346        lookup = '%s'
    4447
  • django/test/testcases.py

    diff --git a/django/test/testcases.py b/django/test/testcases.py
    a b  
    1313from django.core.urlresolvers import clear_url_caches
    1414from django.db import (transaction, connection, connections, DEFAULT_DB_ALIAS,
    1515    reset_queries)
     16from django.db.utils import IntegrityError
    1617from django.http import QueryDict
    1718from django.test import _doctest as doctest
    1819from django.test.client import Client
     
    298299            return
    299300        super(TransactionTestCase, self).__call__(result)
    300301        try:
    301             self._post_teardown()
     302            self._post_teardown(result)
    302303        except (KeyboardInterrupt, SystemExit):
    303304            raise
    304305        except Exception:
     
    306307            result.addError(self, sys.exc_info())
    307308            return
    308309
    309     def _post_teardown(self):
     310    def _post_teardown(self, result):
    310311        """ Performs any post-test things. This includes:
    311312
     313            * Tearing down database fixtures, if any.
    312314            * Putting back the original ROOT_URLCONF if it was changed.
    313315            * Force closing the connection, so that the next test gets
    314316              a clean cursor.
    315317        """
    316         self._fixture_teardown()
     318        self._fixture_teardown(result)
    317319        self._urlconf_teardown()
    318320        # Some DB cursors include SQL statements as part of cursor
    319321        # creation. If you have a test that does rollback, the effect
     
    325327        for connection in connections.all():
    326328            connection.close()
    327329
    328     def _fixture_teardown(self):
     330    def _fixture_teardown(self, result):
    329331        pass
    330332
    331333    def _urlconf_teardown(self):
     
    589591                                                            'database': db
    590592                                                            })
    591593
    592     def _fixture_teardown(self):
     594    def _fixture_teardown(self, result):
    593595        if not connections_support_transactions():
    594596            return super(TestCase, self)._fixture_teardown()
    595597
     
    602604
    603605        restore_transaction_methods()
    604606        for db in databases:
    605             transaction.rollback(using=db)
    606             transaction.leave_transaction_management(using=db)
     607            # Force constraints check execution (on backends that support
     608            # deferring them) before rolling back the transaction.
     609            try:
     610                connections[db].check_constraints()
     611            except IntegrityError:
     612                result.addError(self, sys.exc_info())
     613            finally:
     614                transaction.rollback(using=db)
     615                transaction.leave_transaction_management(using=db)
    607616
    608617def _deferredSkip(condition, reason):
    609618    def decorator(test_func):
  • tests/regressiontests/multiple_database/tests.py

    diff --git a/tests/regressiontests/multiple_database/tests.py b/tests/regressiontests/multiple_database/tests.py
    a b  
    14651465                                                 published=datetime.date(2008, 12, 16))
    14661466
    14671467        marty = Person.objects.using('other').create(pk=1, name="Marty Alchin")
    1468         pro.authors = [marty]
     1468        # Per the router in effect, writes go to the 'default' DB and so the
     1469        # manager will create m2m relationships on that DB. Derive a new manager
     1470        # associated with the 'other' DB so we don't create cross-DB FKs
     1471        author_m2m_manager_in_other_db = pro.authors.db_manager('other')
     1472        author_m2m_manager_in_other_db = [marty]
    14691473
    14701474        self.assertEqual(pro.authors.db, 'other')
    14711475        self.assertEqual(pro.authors.db_manager('default').db, 'default')
Back to Top