Opened 8 months ago

Closed 3 months ago

#33256 closed Cleanup/optimization (fixed)

Some schema tests don't clean up their tables

Reported by: Tim Graham Owned by: Mohammad Ali Mehdizadeh
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Some test errors on a second consecutive run of ./tests/runtests.py --settings=test_postgres --parallel=1 --keepdb schema shows that some tests leave behind their tables. Attached is an initial patch for a couple of the cases.

======================================================================
ERROR: test_add_foreign_key_quoted_db_table (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "table_author_double_quoted" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/django/test/utils.py", line 437, in inner
    return func(*args, **kwargs)
  File "/home/tim/code/django/django/test/testcases.py", line 1305, in skip_wrapper
    return test_func(*args, **kwargs)
  File "/home/tim/code/django/tests/schema/tests.py", line 3229, in test_add_foreign_key_quoted_db_table
    editor.create_model(Author)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 355, in create_model
    self.execute(sql, params or None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "table_author_double_quoted" already exists


======================================================================
ERROR: test_add_foreign_object (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "schema_bookforeignobj" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/tests/schema/tests.py", line 3238, in test_add_foreign_object
    editor.create_model(BookForeignObj)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 355, in create_model
    self.execute(sql, params or None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "schema_bookforeignobj" already exists


======================================================================
ERROR: test_remove_db_index_doesnt_remove_custom_indexes (schema.tests.SchemaTests)
Changing db_index to False doesn't remove indexes from Meta.indexes.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "schema_authorwithindexedname" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/tests/schema/tests.py", line 2659, in test_remove_db_index_doesnt_remove_custom_indexes
    editor.create_model(AuthorWithIndexedName)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 355, in create_model
    self.execute(sql, params or None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "schema_authorwithindexedname" already exists


======================================================================
ERROR: test_remove_field_unique_does_not_remove_meta_constraints (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "schema_authorwithuniquename" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/django/test/testcases.py", line 1305, in skip_wrapper
    return test_func(*args, **kwargs)
  File "/home/tim/code/django/tests/schema/tests.py", line 2057, in test_remove_field_unique_does_not_remove_meta_constraints
    editor.create_model(AuthorWithUniqueName)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 355, in create_model
    self.execute(sql, params or None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "schema_authorwithuniquename" already exists


======================================================================
ERROR: test_remove_index_together_does_not_remove_meta_indexes (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "schema_authorwithindexednameandbirthday" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/django/test/testcases.py", line 1305, in skip_wrapper
    return test_func(*args, **kwargs)
  File "/home/tim/code/django/tests/schema/tests.py", line 2554, in test_remove_index_together_does_not_remove_meta_indexes
    editor.create_model(AuthorWithIndexedNameAndBirthday)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 355, in create_model
    self.execute(sql, params or None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "schema_authorwithindexednameandbirthday" already exists


======================================================================
ERROR: test_remove_unique_together_does_not_remove_meta_constraints (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "schema_authorwithuniquenameandbirthday" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/django/test/testcases.py", line 1305, in skip_wrapper
    return test_func(*args, **kwargs)
  File "/home/tim/code/django/tests/schema/tests.py", line 2176, in test_remove_unique_together_does_not_remove_meta_constraints
    editor.create_model(AuthorWithUniqueNameAndBirthday)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 355, in create_model
    self.execute(sql, params or None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "schema_authorwithuniquenameandbirthday" already exists


======================================================================
ERROR: test_unique_name_quoting (schema.tests.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.DuplicateTable: relation "unique-table" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/tests/schema/tests.py", line 1978, in test_unique_name_quoting
    editor.alter_db_table(TagUniqueRename, old_table_name, 'unique-table')
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 474, in alter_db_table
    self.execute(self.sql_rename_table % {
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 151, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "unique-table" already exists

Attachments (1)

33256-init.diff (1.6 KB) - added by Tim Graham 8 months ago.

Download all attachments as: .zip

Change History (22)

Changed 8 months ago by Tim Graham

Attachment: 33256-init.diff added

comment:1 Changed 8 months ago by Mariusz Felisiak

Triage Stage: UnreviewedAccepted

comment:2 Changed 8 months ago by banani720

Owner: changed from nobody to banani720
Status: newassigned

[]

comment:3 Changed 8 months ago by banani720

If I have not done all of the cases yet, but just want to check in to see if I am going about this the correct way, should I still submit a pr? I've added a try-finally clauses to a couple of the test cases that are mentioned in the error log. This is my first time contributing to an open-source and the tutorial isn't quite clear how I should handle a situation like this. Any guidance would be appreciated.

comment:4 Changed 8 months ago by Mariusz Felisiak

If I have not done all of the cases yet, but just want to check in to see if I am going about this the correct way, should I still submit a pr?

I don't think there is a need to submit PR at this stage. You should be able to run tests locally and check that all schema tests work:

./runtests.py --settings=test_postgres --parallel=1 --keepdb schema

I'd submit PR when all test pass.

comment:5 in reply to:  4 ; Changed 6 months ago by Ayush Joshi

Replying to Mariusz Felisiak:

If I have not done all of the cases yet, but just want to check in to see if I am going about this the correct way, should I still submit a pr?

I don't think there is a need to submit PR at this stage. You should be able to run tests locally and check that all schema tests work:

./runtests.py --settings=test_postgres --parallel=1 --keepdb schema

I'd submit PR when all test pass.

When I run this command I don't know why but I'm getting the following ModuleNotFoundError, could you please help?

Testing against Django installed in '/Python/django/django'
Traceback (most recent call last):
  File "./runtests.py", line 657, in <module>
    failures = django_tests(
  File "./runtests.py", line 348, in django_tests
    test_labels, state = setup_run_tests(verbosity, start_at, start_after, test_labels)
  File "./runtests.py", line 278, in setup_run_tests
    test_modules, state = setup_collect_tests(start_at, start_after, test_labels=test_labels)
  File "./runtests.py", line 193, in setup_collect_tests
    'INSTALLED_APPS': settings.INSTALLED_APPS,
  File "/Python/django/django/conf/__init__.py", line 89, in __getattr__
    self._setup(name)
  File "/Python/django/django/conf/__init__.py", line 76, in _setup
    self._wrapped = Settings(settings_module)
  File "/Python/django/django/conf/__init__.py", line 184, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'test_postgres'

I found that there is a test_postgresql module but when I try to test it

./runtests.py --settings=dbshell.test_postgresql --parallel=1 --keepdb schema

it gives me the following error, could you please help?

Testing against Django installed in '/Python/django/django'
Traceback (most recent call last):
  File "/Python/django/django/utils/connection.py", line 58, in __getitem__
    return getattr(self._connections, alias)
  File "/Python/django/lib/python3.8/site-packages/asgiref/local.py", line 107, in __getattr__
    raise AttributeError(f"{self!r} object has no attribute {key!r}")
AttributeError: <asgiref.local.Local object at 0x7fd81f6d4880> object has no attribute 'default'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./runtests.py", line 657, in <module>
    failures = django_tests(
  File "./runtests.py", line 348, in django_tests
    test_labels, state = setup_run_tests(verbosity, start_at, start_after, test_labels)
  File "./runtests.py", line 278, in setup_run_tests
    test_modules, state = setup_collect_tests(start_at, start_after, test_labels=test_labels)
  File "./runtests.py", line 193, in setup_collect_tests
    'INSTALLED_APPS': settings.INSTALLED_APPS,
  File "/Python/django/django/conf/__init__.py", line 89, in __getattr__
    self._setup(name)
  File "/Python/django/django/conf/__init__.py", line 76, in _setup
    self._wrapped = Settings(settings_module)
  File "/Python/django/django/conf/__init__.py", line 184, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Python/django/tests/dbshell/test_postgresql.py", line 13, in <module>
    class PostgreSqlDbshellCommandTestCase(SimpleTestCase):
  File "/Python/django/tests/dbshell/test_postgresql.py", line 140, in PostgreSqlDbshellCommandTestCase
    @skipUnless(connection.vendor == 'postgresql', 'Requires a PostgreSQL connection')
  File "/Python/django/django/utils/connection.py", line 15, in __getattr__
    return getattr(self._connections[self._alias], item)
  File "/Python/django/django/utils/connection.py", line 60, in __getitem__
    if alias not in self.settings:
  File "/Python/django/django/utils/functional.py", line 56, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Python/django/django/utils/connection.py", line 45, in settings
    self._settings = self.configure_settings(self._settings)
  File "/Python/django/django/db/utils.py", line 144, in configure_settings
    databases = super().configure_settings(databases)
  File "/Python/django/django/utils/connection.py", line 50, in configure_settings
    settings = getattr(django_settings, self.settings_name)
  File "/Python/django/django/conf/__init__.py", line 89, in __getattr__
    self._setup(name)
  File "/Python/django/django/conf/__init__.py", line 76, in _setup
    self._wrapped = Settings(settings_module)
  File "/Python/django/django/conf/__init__.py", line 204, in __init__
    warnings.warn(
django.utils.deprecation.RemovedInDjango50Warning: The default value of USE_TZ will change from False to True in Django 5.0. Set USE_TZ to False in your project settings if you want to keep the current default behavior.
Last edited 6 months ago by Ayush Joshi (previous) (diff)

comment:6 in reply to:  5 Changed 6 months ago by Mariusz Felisiak

Replying to Ayush Joshi:

When I run this command I don't know why but I'm getting the following ModuleNotFoundError, could you please help?

--settings should be a path to your settings (see docs) not a test module. If you're having trouble understanding how Django works, see TicketClosingReasons/UseSupportChannels for ways to get help.

comment:7 Changed 4 months ago by Mohammad Ali Mehdizadeh

Can I work on this ticket please?

comment:8 in reply to:  description Changed 3 months ago by Mohammad Ali Mehdizadeh

I run the command but I can't produce errors, every thing works nice.

(django-venv) root@DESKTOP-N10114T:/mnt/d/mycode/django# ./tests/runtests.py --settings=test_postgres --parallel=1 --keepdb schema
Testing against Django installed in '/mnt/d/mycode/django/django'
Found 176 test(s).
Using existing test database for alias 'default'...
System check identified no issues (0 silenced).
.s................sss...s.ss.....s..ss.sss.s......ss.s......................s.............s.....................s..s....s...s.....................s.............s.....
.s...s...s
----------------------------------------------------------------------
Ran 176 tests in 11.057s

OK (skipped=28)
Preserving test database for alias 'default'...
Last edited 3 months ago by Tim Graham (previous) (diff)

comment:9 Changed 3 months ago by Tim Graham

Have you run the command a second time so that you're reusing an existing database?

comment:10 Changed 3 months ago by Mohammad Ali Mehdizadeh

Owner: changed from banani720 to Mohammad Ali Mehdizadeh

comment:11 in reply to:  9 Changed 3 months ago by Mohammad Ali Mehdizadeh

Replying to Tim Graham:

Have you run the command a second time so that you're reusing an existing database?

No, I use a new instance of postgres and I check the databases and remove test_ database each time.
But I can't produce errors.

comment:12 Changed 3 months ago by Mohammad Ali Mehdizadeh

This is my test_postgres.py file:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'postgres_user',
        'PASSWORD': 'postgres_password',
        'HOST': 'postgres_host',
        'PORT': 'postgres_port',
    },
    'other': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'postgres_user',
        'PASSWORD': 'postgres_password',
        'HOST': 'postgres_host',
        'PORT': 'postgres_port',
    },
}

SECRET_KEY = "django_tests_secret_key"

# Use a fast hasher to speed up tests.
PASSWORD_HASHERS = [
    "django.contrib.auth.hashers.MD5PasswordHasher",
]

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

USE_TZ = False

comment:13 Changed 3 months ago by Tim Graham

The errors happen on a second consecutive test run (and don't remove the existing database between test runs).

comment:15 in reply to:  13 Changed 3 months ago by Mohammad Ali Mehdizadeh

Replying to Tim Graham:

Thank you for guidance, I create the same error.
So have you any idea how to solve this issue?

comment:16 Changed 3 months ago by Tim Graham

I attached an initial patch to this ticket. You should apply similar techniques to other tests.

comment:17 in reply to:  16 Changed 3 months ago by Mohammad Ali Mehdizadeh

Replying to Tim Graham:
Do you have any idea, how to write a test for this scenario.

comment:18 Changed 3 months ago by Tim Graham

You only need to fix the existing errors. No additional tests are needed.

comment:19 Changed 3 months ago by Mohammad Ali Mehdizadeh

Has patch: set

Tim Graham:
Nice
I create a PR https://github.com/django/django/pull/15528
feel free to feedback me

Last edited 3 months ago by Mohammad Ali Mehdizadeh (previous) (diff)

comment:20 Changed 3 months ago by Mariusz Felisiak

Patch needs improvement: set

comment:21 Changed 3 months ago by Mariusz Felisiak

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:22 Changed 3 months ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In 4b66a5e6:

Fixed #33256 -- Fixed schema test failures when using --keepdb.

Note: See TracTickets for help on using tickets.
Back to Top