2010-02-11 17 views
1

Juste ajouté geoDjango et déplacé la base de données vers PostGIS. J'ai un tas de tests unitaires qui passent individuellement, mais lorsqu'ils sont exécutés ensemble, j'obtiens un IntenalError, la base de données étant grincheuse entre les tests. Le modèle qui est utilisé dans ces tests est un modèle django.contrib.gis.db. Les tests héritent même de TransactionTestCase au lieu de la classe TestCase standard. Même situation pour les deux. Chose amusante, quand je retourne à MySQL, ils fonctionnent tous très bien. Mais je ne peux pas rester sur MySQL car j'ai besoin d'écrire des requêtes de distance à côté.Obtenir "InternalError: pas de point de sauvegarde" avec PostGIS dans Django même lors de l'utilisation de TransactionTestCase

Comment automatiser ces tests dans geoDjango avec postgres? Que fais-je?


P.S. OUI: J'ai les choses settings.py:

DATABASE_ENGINE = 'postgresql_psycopg2' 
..... 
TEST_RUNNER='django.contrib.gis.tests.run_tests' 
POSTGIS_TEMPLATE='template_postgis' 
POSTGIS_SQL_PATH='/usr/share/postgresql-8.3-postgis/' 

est ici la trace de la pile:

..EEE 
====================================================================== 
ERROR: a valid address should yeild redirect to the profile page 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 242, in __call__ 
    self._pre_setup() 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 217, in _pre_setup 
    self._fixture_setup() 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 222, in _fixture_setup 
    call_command('flush', verbosity=0, interactive=False) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 166, in call_command 
    return klass.execute(*args, **defaults) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/base.py", line 222, in execute 
    output = self.handle(*args, **options) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/base.py", line 351, in handle 
    return self.handle_noargs(**options) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/commands/flush.py", line 61, in handle_noargs 
    emit_post_sync_signal(models.get_models(), verbosity, interactive) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/sql.py", line 205, in emit_post_sync_signal 
    interactive=interactive) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/dispatch/dispatcher.py", line 166, in send 
    response = receiver(signal=self, sender=sender, **named) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/contrib/auth/management/__init__.py", line 28, in create_permissions 
    defaults={'name': name, 'content_type': ctype}) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/models/manager.py", line 123, in get_or_create 
    return self.get_query_set().get_or_create(**kwargs) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/models/query.py", line 339, in get_or_create 
    transaction.savepoint_rollback(sid) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/transaction.py", line 199, in savepoint_rollback 
    connection._savepoint_rollback(sid) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/__init__.py", line 67, in _savepoint_rollback 
    self.cursor().execute(self.ops.savepoint_rollback_sql(sid)) 
InternalError: no such savepoint 


====================================================================== 
ERROR: test_repair_types (rubbercan_profiles.tests.test_view.TestProfileView) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 242, in __call__ 
    self._pre_setup() 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 217, in _pre_setup 
    self._fixture_setup() 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 222, in _fixture_setup 
    call_command('flush', verbosity=0, interactive=False) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 166, in call_command 
    return klass.execute(*args, **defaults) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/base.py", line 222, in execute 
    output = self.handle(*args, **options) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/base.py", line 351, in handle 
    return self.handle_noargs(**options) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/commands/flush.py", line 31, in handle_noargs 
    sql_list = sql_flush(self.style, only_django=True) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/sql.py", line 128, in sql_flush 
    tables = connection.introspection.django_table_names(only_existing=True) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/__init__.py", line 510, in django_table_names 
    tables = [t for t in tables if self.table_name_converter(t) in self.table_names()] 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/__init__.py", line 491, in table_names 
    return self.get_table_list(cursor) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/postgresql/introspection.py", line 30, in get_table_list 
    AND pg_catalog.pg_table_is_visible(c.oid)""") 
InternalError: current transaction is aborted, commands ignored until end of transaction block 


====================================================================== 
ERROR: test_zip_code_length (rubbercan_profiles.tests.test_view.TestProfileView) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 242, in __call__ 
    self._pre_setup() 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 217, in _pre_setup 
    self._fixture_setup() 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/test/testcases.py", line 222, in _fixture_setup 
    call_command('flush', verbosity=0, interactive=False) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 166, in call_command 
    return klass.execute(*args, **defaults) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/base.py", line 222, in execute 
    output = self.handle(*args, **options) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/base.py", line 351, in handle 
    return self.handle_noargs(**options) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/commands/flush.py", line 31, in handle_noargs 
    sql_list = sql_flush(self.style, only_django=True) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/core/management/sql.py", line 128, in sql_flush 
    tables = connection.introspection.django_table_names(only_existing=True) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/__init__.py", line 510, in django_table_names 
    tables = [t for t in tables if self.table_name_converter(t) in self.table_names()] 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/__init__.py", line 491, in table_names 
    return self.get_table_list(cursor) 
    File "/home/hendrixski/rubvirtenv/lib/python2.6/site-packages/django/db/backends/postgresql/introspection.py", line 30, in get_table_list 
    AND pg_catalog.pg_table_is_visible(c.oid)""") 
InternalError: current transaction is aborted, commands ignored until end of transaction block 


---------------------------------------------------------------------- 
Ran 2 tests in 24.592s 

et voici les tests unitaires:

from django.contrib.auth.models import User 
from django.core.urlresolvers import reverse 
from django.test import TransactionTestCase 
from django.test.client import Client 
from django.contrib.auth.models import User 
from geopy import geocoders 
from exceptions import ValueError, KeyError 
from rubbercan_profiles.forms import ProfileForm 
from rubbercan_profiles.models import Profile 
from django.conf import settings 
from django.core.urlresolvers import reverse 
from django.contrib.gis.maps.google import GoogleMap, GMarker 

class TestProfileView(TransactionTestCase): 
    fixtures = ['test_rc_profiles.json'] 

    def setUp(self): 
     self.c = Client() 
     self.c.login(username="asdf", password="asdf") 

    def tearDown(self): 
     self.c.logout() 

    def test_repair_types(self): 
     """ 
     Verify that the repair types are being accessed properly from the templates and displayed properly 
     """ 
     #verify the setup is what we expect 
     u1 = User.objects.get(username="asdf") 
     self.assertTrue("Collision repair" in u1.get_profile().repair_types) 
     #it should display on the page as well   
     response = self.c.get(reverse("profile_detail", args=['asdf'])) 
     self.assertContains(response, "Collision repair") 


    def test_zip_code_length(self): 
     """ 
     For some reason min_value and min_length didn't work on the model field. 
     So we have our own form validator that makes sure the length of the zipcode is long enough, 
     and that it's not too long. In a perfect world, we could identify whether the zipcode exists or not, 
     but we do not do this yet. 
     """ 
     #empty input 
     response=self.c.post(reverse("profile_edit"), {"name": "Barnaby", "zipCode": ""}) 
     self.assertFormError(response, 'profile_form', 'zipCode', [u'This field is required.']) 

     #too short input 
     response=self.c.post(reverse("profile_edit"), {"name": "Barnaby", "zipCode": 941}) 
     self.assertFormError(response, 'profile_form', 'zipCode', [u'Please enter a valid zipcode.']) 


    def test_bad_geocoding(self): 
     """ 
     When a bad address is passed to the form, it should indicate the error at the top of the form. 
     in the forms NON_FIELD_ERRORS 
     """ 
     badZipCode = 99916 
     g = geocoders.Google(settings.GOOGLE_MAPS_API_KEY) 
     self.assertRaises(ValueError, g.geocode, badZipCode) 
     response=self.c.post(reverse("profile_edit"), {"name": "Barnaby", "zipCode": badZipCode}) 
     self.assertContains(response, "Please enter a valid address") 

     response=self.c.post(reverse("profile_edit"), {"name": "Barnaby", "street": "2311 23nd Ave", 
                 "city": "San Francisco", "state": "CA", "zipCode": badZipCode}) 
     self.assertContains(response, "Please enter a valid address")   
     #TODO check that the non_field_errors are getting it 

    def test_good_geocoding(self): 
     "a valid address should yeild redirect to the profile page" 
     response=self.c.post(reverse("profile_edit"), {"street": "2311 32nd Ave", "city": "San Francisco", 
                 "name": "barnaby", "state": "CA", "zipCode": 94116}) 
     self.assertRedirects(response, reverse("profile_detail", args=['asdf']), 302) 


    def context_lookup(self, response, key): 
     "Stupid hack for 1.0.3 backwards compatability" 
     # used for debugging 
     for subcontext in response.context: 
      if key in subcontext: 
       return subcontext[key] 
     raise KeyError 


    def test_gmap(self): 
     """ 
     Shops should pass a google maps item to the template, so that we can display their 
     location for customers to see. 
     Customers should NOT pass a google map into their template 
     """ 
     #assuming bob is a shop and has a point, he gets a map 
     bobCheck = Profile.objects.get(id=1) 
     assert bobCheck.point is not None 
     self.assertEqual(bobCheck.status, Profile.REPAIR_SHOP) 
     response = self.c.get(reverse("profile_detail", args=['bob'])) 
     assert isinstance(self.context_lookup(response, 'google'), GoogleMap) 


     #assuming joe is not a shop, his profile doesn't show a map 
     joeCheck = Profile.objects.get(id=2) 
     self.assertEqual(joeCheck.status, Profile.CUSTOMER) 
     response = self.c.get(reverse("profile_detail", args=['joe'])) 
     self.assertRaises(KeyError, self.context_lookup, response, 'google') 

     #assuming asdf is a shop, but doesn't have a point, 
     #when he views his profile he should be prompted about his profile being incomplete 
     asdfCheck = Profile.objects.get(id=3) 
     assert asdfCheck.point is None 
     self.assertEqual(asdfCheck.status, Profile.REPAIR_SHOP) 
     response = self.c.get(reverse("profile_detail", args=['asdf'])) 
     self.assertRaises(KeyError, self.context_lookup, response, 'google') 
     self.assertContains(response, "incomplete") 

Et, voici ce que les postgres Le log ressemble à:

[email protected]:/var/log$ tail -60 pgsql 
Feb 11 12:57:51 hendrixski postgres[13506]: [142-1] 2010-02-11 12:57:51 PST LOG: statement: INSERT INTO "auth_permission" ("name", "content_type_id", "codename") VALUES (E'Can 
Feb 11 12:57:51 hendrixski postgres[13506]: [142-2] delete group', 2, E'delete_group') 
Feb 11 12:57:51 hendrixski postgres[13506]: [143-1] 2010-02-11 12:57:51 PST LOG: statement: SELECT CURRVAL('"auth_permission_id_seq"') 
Feb 11 12:57:51 hendrixski postgres[13506]: [144-1] 2010-02-11 12:57:51 PST LOG: statement: COMMIT 
Feb 11 12:57:51 hendrixski postgres[13506]: [145-1] 2010-02-11 12:57:51 PST LOG: statement: BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
Feb 11 12:57:51 hendrixski postgres[13506]: [146-1] 2010-02-11 12:57:51 PST LOG: statement: SELECT "auth_permission"."id", "auth_permission"."name", 
Feb 11 12:57:51 hendrixski postgres[13506]: [146-2] "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "django_content_type" ON 
Feb 11 12:57:51 hendrixski postgres[13506]: [146-3] ("auth_permission"."content_type_id" = "django_content_type"."id") WHERE ("auth_permission"."codename" = E'add_user' AND 
Feb 11 12:57:51 hendrixski postgres[13506]: [146-4] "auth_permission"."content_type_id" = 3) ORDER BY "django_content_type"."app_label" ASC, "auth_permission"."codename" ASC 
Feb 11 12:57:51 hendrixski postgres[13506]: [147-1] 2010-02-11 12:57:51 PST LOG: statement: SAVEPOINT s1217292608_x1 
Feb 11 12:57:51 hendrixski postgres[13506]: [148-1] 2010-02-11 12:57:51 PST LOG: statement: INSERT INTO "auth_permission" ("name", "content_type_id", "codename") VALUES (E'Can add 
Feb 11 12:57:51 hendrixski postgres[13506]: [148-2] user', 3, E'add_user') 
Feb 11 12:57:51 hendrixski postgres[13506]: [149-1] 2010-02-11 12:57:51 PST LOG: statement: SELECT CURRVAL('"auth_permission_id_seq"') 
Feb 11 12:57:51 hendrixski postgres[13506]: [150-1] 2010-02-11 12:57:51 PST LOG: statement: COMMIT 
Feb 11 12:57:51 hendrixski postgres[13506]: [151-1] 2010-02-11 12:57:51 PST ERROR: insert or update on table "auth_permission" violates foreign key constraint 
Feb 11 12:57:51 hendrixski postgres[13506]: [151-2] "content_type_id_refs_id_728de91f" 
Feb 11 12:57:51 hendrixski postgres[13506]: [151-3] 2010-02-11 12:57:51 PST DETAIL: Key (content_type_id)=(3) is not present in table "django_content_type". 
Feb 11 12:57:51 hendrixski postgres[13506]: [151-4] 2010-02-11 12:57:51 PST STATEMENT: COMMIT 
Feb 11 12:57:51 hendrixski postgres[13506]: [152-1] 2010-02-11 12:57:51 PST LOG: statement: BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
Feb 11 12:57:51 hendrixski postgres[13506]: [153-1] 2010-02-11 12:57:51 PST LOG: statement: ROLLBACK TO SAVEPOINT s1217292608_x1 
Feb 11 12:57:51 hendrixski postgres[13506]: [154-1] 2010-02-11 12:57:51 PST ERROR: no such savepoint 
Feb 11 12:57:51 hendrixski postgres[13506]: [154-2] 2010-02-11 12:57:51 PST STATEMENT: ROLLBACK TO SAVEPOINT s1217292608_x1 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-1] 2010-02-11 12:57:51 PST LOG: statement: 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-2] #011   SELECT c.relname 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-3] #011   FROM pg_catalog.pg_class c 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-4] #011   LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-5] #011   WHERE c.relkind IN ('r', 'v', '') 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-6] #011    AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
Feb 11 12:57:51 hendrixski postgres[13506]: [155-7] #011    AND pg_catalog.pg_table_is_visible(c.oid) 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-1] 2010-02-11 12:57:51 PST ERROR: current transaction is aborted, commands ignored until end of transaction block 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-2] 2010-02-11 12:57:51 PST STATEMENT: 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-3] #011   SELECT c.relname 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-4] #011   FROM pg_catalog.pg_class c 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-5] #011   LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-6] #011   WHERE c.relkind IN ('r', 'v', '') 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-7] #011    AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
Feb 11 12:57:51 hendrixski postgres[13506]: [156-8] #011    AND pg_catalog.pg_table_is_visible(c.oid) 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-1] 2010-02-11 12:57:51 PST LOG: statement: 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-2] #011   SELECT c.relname 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-3] #011   FROM pg_catalog.pg_class c 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-4] #011   LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-5] #011   WHERE c.relkind IN ('r', 'v', '') 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-6] #011    AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
Feb 11 12:57:51 hendrixski postgres[13506]: [157-7] #011    AND pg_catalog.pg_table_is_visible(c.oid) 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-1] 2010-02-11 12:57:51 PST ERROR: current transaction is aborted, commands ignored until end of transaction block 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-2] 2010-02-11 12:57:51 PST STATEMENT: 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-3] #011   SELECT c.relname 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-4] #011   FROM pg_catalog.pg_class c 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-5] #011   LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-6] #011   WHERE c.relkind IN ('r', 'v', '') 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-7] #011    AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
Feb 11 12:57:51 hendrixski postgres[13506]: [158-8] #011    AND pg_catalog.pg_table_is_visible(c.oid) 
Feb 11 12:57:51 hendrixski postgres[13506]: [159-1] 2010-02-11 12:57:51 PST LOG: statement: ROLLBACK 
Feb 11 12:57:51 hendrixski postgres[13507]: [3-1] 2010-02-11 12:57:51 PST LOG: statement: SET DATESTYLE TO 'ISO' 
Feb 11 12:57:51 hendrixski postgres[13507]: [4-1] 2010-02-11 12:57:51 PST LOG: statement: SHOW client_encoding 
Feb 11 12:57:51 hendrixski postgres[13507]: [5-1] 2010-02-11 12:57:51 PST LOG: statement: SHOW default_transaction_isolation 
Feb 11 12:57:51 hendrixski postgres[13507]: [6-1] 2010-02-11 12:57:51 PST LOG: statement: BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
Feb 11 12:57:51 hendrixski postgres[13507]: [7-1] 2010-02-11 12:57:51 PST LOG: statement: SET TIME ZONE E'US/Eastern' 
Feb 11 12:57:51 hendrixski postgres[13507]: [8-1] 2010-02-11 12:57:51 PST LOG: statement: ROLLBACK 
Feb 11 12:57:52 hendrixski postgres[13507]: [9-1] 2010-02-11 12:57:52 PST LOG: statement: DROP DATABASE "test_rubbercan" 

Répondre

1

Hopefu Cela aide quelqu'un à économiser beaucoup de temps! J'ai trouvé le coupable! Une demande distincte pour les commentaires: http://pypi.python.org/pypi/django-reviews/0.2.1

Je vais essayer de contacter l'auteur et de diagnostiquer davantage cela, peut-être le faire réparer.

Homme qui a beaucoup travaillé.