ID de objeto django incrementan entre pruebas unitarias

Estoy usando Django 1.2.3-3 + squeeze1 en Debian squeeze con PostgreSQL 8.4.7-0squeeze2 (aunque no creo que PostgreSQL sea relevante aquí), y ejecuto pruebas de unidad de Django basadas en unittest con el siguiente setUp y tearDown

def setUp(self): print "running setup" self.c = Client() self.user = User.objects.create_user('faheem', 'faheem@email.unc.edu', 'foo') self.logged_in = self.c.login(username='faheem', password='foo') settings.MEDIA_ROOT='/tmp/' #settings.ZIP_UPLOAD='/var/tmp/zip/' def tearDown(self): print "running teardown" FolderUpload.objects.all().delete() FileUpload.objects.all().delete() ZipFileUpload.objects.all().delete() OldFileUpload.objects.all().delete() # FIXME: Quick & dirty fix for the time being. Should make this a delete method. os.system("rm -rf "+ settings.ZIP_UPLOAD + "/*") 

La idea es que todo se elimine de la base de datos entre las pruebas unitarias en ejecución. De acuerdo con la documentación de unittest, para eso está tearDown . El problema que tengo es que todavía parece haber algún estado guardado entre las diferentes pruebas unitarias. Específicamente, estoy viendo que las identificaciones se incrementan. Entonces digamos que si creo un objeto ZipFileUpload en test1 , y luego creo un objeto ZipFileUpload en test2 , entonces esperaría que ambas identificaciones sean 1 , pero lo que veo es que es id 1 para test1 y id 2 para test2 . Esto tendría sentido si los ID provienen de algún índice que vive fuera de estas tablas. No sé lo suficiente sobre cómo Diango hace esto para saber si ese es realmente el caso. Si lo están haciendo de esta manera, no tengo idea de por qué. Cualquier aclaración sobre este punto sería apreciada.

En cualquier caso, me conformaría con una forma limpia de eliminar la base de datos, si alguien puede sugerir una. Este método probablemente debería ir en teadDown . La prueba de aplicaciones Django menciona la siguiente función, pero no pude importarla desde django.test.utils . Confusamente, esta función parece estar en django/db/backends/creation.py .

destroy_test_db (old_database_name, verbosity = 1)

Destruye la base de datos cuyo nombre está almacenado en NOMBRE en las BASES DE DATOS, y establece que NOMBRE use el nombre provisto.

La primera parte de esta oración está bien: “Destruye la base de datos cuyo nombre está almacenado en NOMBRE en las BASES DE DATOS”, pero ¿qué significa “establece NOMBRE para usar el nombre provisto”? Supongo que el nombre proporcionado es old_database_name ,

No está claro qué NAME está en el contexto. ¿Es el NAME en DATABASES NAME DATABASES , y si es así, por qué necesito configurar algo que ya está configurado? Supongo que el nombre proporcionado es old_database_name , pero si es así, ¿por qué querría establecerlo en un argumento llamado old_database_name ? Esta oración no ha cambiado en los documentos de desarrollo.

EDITAR:

Después de una respuesta de Steve Mayne (ver más abajo), pensé que me gustaría elaborar un poco más sobre el trasfondo de esto.

Esta aplicación se redactó originalmente durante 2007/2008/2009, incluidas las pruebas unitarias. Durante la mayor parte de ese tiempo, estuve usando versiones previas a 1.0 de Django. Según el Historial de lanzamientos de Django de Ken Cochran , 1.0 se lanzó el 3 de septiembre de 2008. La configuración descrita funcionó bien durante ese tiempo. Veo que la función tearDown anterior fue escrita originalmente en diciembre de 2007. Entonces, ¿tal vez el comportamiento de Django cambió?

En retrospectiva, me doy cuenta de que vaciar las tablas, como tearDown hace tearDown anteriormente, no garantiza que el recuento de ID se restablezca a 1 , ya que la secuencia puede ser un objeto separado de la tabla.

Gracias a Steve por su solución. Si existe, me gustaría escuchar acerca de una solución portátil para restablecer la secuencia. También me interesaría una explicación de cómo hacer que la función destroy_test_db anterior funcione.

Puede restablecer la secuencia de ID en cada tabla utilizando el siguiente SQL:

 SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), 1); 

Solo debes hacer esto si tu mesa está vacía.