Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #30172 -- Prevented Meta constraints from being removed in other migration operations. #10978

Conversation

tbicr
Copy link
Contributor

@tbicr tbicr commented Feb 11, 2019

@tbicr tbicr force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from 9471a3a to c2a73ec Compare February 12, 2019 22:17
@tbicr
Copy link
Contributor Author

tbicr commented Feb 12, 2019

issue still actual for unique constraints for sqlite, that related to sqlite introspection bug: https://code.djangoproject.com/ticket/30183

@tbicr tbicr force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from c2a73ec to a728d46 Compare February 13, 2019 07:16
Copy link
Contributor

@auvipy auvipy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix the flake8 error plz

@tbicr tbicr force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from a728d46 to 23a85b1 Compare March 11, 2019 08:53
@tbicr
Copy link
Contributor Author

tbicr commented Mar 11, 2019

fix the flake8 error plz

fixed

@tbicr tbicr force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from 23a85b1 to d062194 Compare March 11, 2019 09:24
@timgraham
Copy link
Member

Is #11005 no longer a dependency of this?

@timgraham
Copy link
Member

Oracle errors:

======================================================================
ERROR: test_remove_field_uniqueness_does_not_remove_custom_constraints (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)
  File "/home/tim/code/django/django/db/backends/oracle/base.py", line 510, in execute
    return self.cursor.execute(query, self._param_generator(params))
cx_Oracle.DatabaseError: ORA-02261: such unique or primary key already exists in the table

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 1739, in test_remove_field_uniqueness_does_not_remove_custom_constraints
    editor.add_constraint(AuthorWithUniqueName, constraint)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 346, in add_constraint
    self.execute(sql)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 138, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 67, 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 76, 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 89, 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)
  File "/home/tim/code/django/django/db/backends/oracle/base.py", line 510, in execute
    return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-02261: such unique or primary key already exists in the table

======================================================================
ERROR: test_remove_index_together_does_not_remove_custom_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)
  File "/home/tim/code/django/django/db/backends/oracle/base.py", line 510, in execute
    return self.cursor.execute(query, self._param_generator(params))
cx_Oracle.DatabaseError: ORA-01408: such column list already indexed

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 1998, in test_remove_index_together_does_not_remove_custom_indexes
    editor.add_index(AuthorWithIndexedNameAndBirthday, index)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 336, in add_index
    self.execute(index.create_sql(model, self), params=None)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 138, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 67, 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 76, 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 89, 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)
  File "/home/tim/code/django/django/db/backends/oracle/base.py", line 510, in execute
    return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-01408: such column list already indexed

======================================================================
ERROR: test_remove_unique_together_does_not_remove_custom_constraints (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)
  File "/home/tim/code/django/django/db/backends/oracle/base.py", line 510, in execute
    return self.cursor.execute(query, self._param_generator(params))
cx_Oracle.DatabaseError: ORA-02261: such unique or primary key already exists in the table

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 1866, in test_remove_unique_together_does_not_remove_custom_constraints
    editor.add_constraint(AuthorWithUniqueNameAndBirthday, constraint)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 346, in add_constraint
    self.execute(sql)
  File "/home/tim/code/django/django/db/backends/base/schema.py", line 138, in execute
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 67, 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 76, 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 89, 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)
  File "/home/tim/code/django/django/db/backends/oracle/base.py", line 510, in execute
    return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-02261: such unique or primary key already exists in the table

@tbicr tbicr force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from d062194 to c07b4e6 Compare March 13, 2019 20:15
@tbicr
Copy link
Contributor Author

tbicr commented Mar 13, 2019

Is #11005 no longer a dependency of this?

Yep, removed skipIf for sqlite

Oracle errors:

Look like oracle doesn't have issue that solve this MR for another databases because it forbid same field constraints creation on database level.

So one of approaches can be to skip this tests for oracle.

Another side: for me oracle behavior looks logical and another way to solve issue can be forbid to create/change model with same fields constraints (if you didn't create it yet).

However this two approaches quite separate and can be done with different tickets, what do you think?

Copy link
Member

@timgraham timgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm okay with skipping the test on Oracle.


# Drop the check constraint
with connection.schema_editor() as editor:
AuthorWithUniqueName._meta.constraints = [] # sqlite hack
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd want more details about why this hack is needed.

Copy link
Member

@carltongibson carltongibson Mar 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the AuthorWithUniqueName an error? Shouldn't it be Author in this test? (The similar lines in the other tests use the model adjusted in that test.)

But if so, it's not causing a failure on SQLite, so what's it for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added details

chaged AuthorWithUniqueName to Author, it doesn't raise because remove_constraint for sqlite use model._meta.constraints when recreate table and just had incorrect state in database after test run

# Ensure the constraints exist
constraints = self.get_constraints(Author._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
self.assertEqual(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be more readable and consistent with our indentation style with something like:

foo_constraints = [
    name  for name, details in constraints.items()
    if details['columns'] == ['name'] and details['unique'] and name != custom_constraint_name]
]
self.assertEqual(len(foo_constraints), 1)

(choosing a different name than "foo"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

# Create table
with connection.schema_editor() as editor:
editor.create_model(AuthorWithUniqueName)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can omit the blank line before each comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


# Drop the check constraint
with connection.schema_editor() as editor:
AuthorWithUniqueName._meta.constraints = [] # sqlite hack
Copy link
Member

@carltongibson carltongibson Mar 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the AuthorWithUniqueName an error? Shouldn't it be Author in this test? (The similar lines in the other tests use the model adjusted in that test.)

But if so, it's not causing a failure on SQLite, so what's it for?

@@ -1671,6 +1731,60 @@ class Meta:
with self.assertRaises(IntegrityError):
Tag.objects.create(title='bar', slug='foo')

def test_remove_field_uniqueness_does_not_remove_custom_constraints(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_removing_field_constraint_does_not_remove_meta_constraint? (Similar for other tests?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, look like I miss point of you questions, by the way all tests in PR pretty similar

constraint = CheckConstraint(check=Q(height__gte=0), name='author_height_gte_0_check')
custom_constraint_name = constraint.name

try:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: the try...finally... is just to ensure test isolation yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, looks it unnecessary when state cleaned with last lines of test, so just removed it

@tbicr tbicr force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from c07b4e6 to d9be31f Compare March 15, 2019 21:13
@tbicr
Copy link
Contributor Author

tbicr commented Mar 15, 2019

I'm okay with skipping the test on Oracle.

added skipIf for oracle

@timgraham timgraham force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from d9be31f to 293e8c0 Compare March 18, 2019 00:26
@timgraham timgraham changed the title Fixed #30172 -- meta index constraint conflict with same field constraints removing Fixed #30172 -- Prevented Meta constraints from being removed in other migration operations. Mar 18, 2019
@timgraham timgraham force-pushed the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch from 293e8c0 to 5c17c27 Compare March 18, 2019 00:51
@timgraham timgraham merged commit 5c17c27 into django:master Mar 18, 2019
@charettes
Copy link
Member

Thanks for hardwork here @tbicr and @timgraham.

@tbicr tbicr deleted the fix-meta-index-constraint-conflict-with-same-field-constraints-removing branch March 18, 2019 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants