Skip to content

Commit f007803

Browse files
committed
add validation of broken transactions
1 parent 44bfab1 commit f007803

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

django_mongodb_backend/compiler.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ def execute_sql(self, returning_fields=None):
685685
@wrap_database_errors
686686
def insert(self, docs, returning_fields=None):
687687
"""Store a list of documents using field columns as element names."""
688+
self.connection.validate_no_broken_transaction()
688689
inserted_ids = self.collection.insert_many(
689690
docs, session=self.connection.session
690691
).inserted_ids
@@ -770,6 +771,7 @@ def execute_sql(self, result_type):
770771

771772
@wrap_database_errors
772773
def update(self, criteria, pipeline):
774+
self.connection.validate_no_broken_transaction()
773775
return self.collection.update_many(
774776
criteria, pipeline, session=self.connection.session
775777
).matched_count

django_mongodb_backend/features.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
4848
"aggregation.tests.AggregateTestCase.test_order_by_aggregate_transform",
4949
# 'NulledTransform' object has no attribute 'as_mql'.
5050
"lookup.tests.LookupTests.test_exact_none_transform",
51-
# "Save with update_fields did not affect any rows."
52-
"basic.tests.SelectOnSaveTests.test_select_on_save_lying_update",
5351
# BaseExpression.convert_value() crashes with Decimal128.
5452
"aggregation.tests.AggregateTestCase.test_combine_different_types",
5553
"annotations.tests.NonAggregateAnnotationTestCase.test_combined_f_expression_annotation_with_aggregation",
@@ -84,8 +82,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
8482
# Value.as_mql() doesn't call output_field.get_db_prep_save():
8583
# https://github.com/mongodb/django-mongodb-backend/issues/282
8684
"model_fields.test_jsonfield.TestSaveLoad.test_bulk_update_custom_get_prep_value",
87-
# to debug
88-
"transactions.tests.AtomicMiscTests.test_mark_for_rollback_on_error_in_transaction",
8985
}
9086
# $bitAnd, #bitOr, and $bitXor are new in MongoDB 6.3.
9187
_django_test_expected_failures_bitwise = {
@@ -96,11 +92,32 @@ class DatabaseFeatures(BaseDatabaseFeatures):
9692
"expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor_right_null",
9793
"expressions.tests.ExpressionOperatorTests.test_lefthand_transformed_field_bitwise_or",
9894
}
95+
_django_test_expected_failures_no_transactions = {
96+
# "Save with update_fields did not affect any rows." instead of
97+
# "An error occurred in the current transaction. You can't execute
98+
# queries until the end of the 'atomic' block."
99+
"basic.tests.SelectOnSaveTests.test_select_on_save_lying_update",
100+
}
99101
_django_test_expected_failures_transactions = {
100102
# When update_or_create() fails with IntegrityError, the transaction
101103
# is no longer usable.
102104
"get_or_create.tests.UpdateOrCreateTests.test_manual_primary_key_test",
103105
"get_or_create.tests.UpdateOrCreateTestsWithManualPKs.test_create_with_duplicate_primary_key",
106+
# Tests that require savepoints
107+
"admin_views.tests.AdminViewBasicTest.test_disallowed_to_field",
108+
"admin_views.tests.AdminViewPermissionsTest.test_add_view",
109+
"admin_views.tests.AdminViewPermissionsTest.test_change_view",
110+
"admin_views.tests.AdminViewPermissionsTest.test_change_view_save_as_new",
111+
"admin_views.tests.AdminViewPermissionsTest.test_delete_view",
112+
"auth_tests.test_views.ChangelistTests.test_view_user_password_is_readonly",
113+
"get_or_create.tests.GetOrCreateTests.test_get_or_create_invalid_params",
114+
"get_or_create.tests.UpdateOrCreateTests.test_integrity",
115+
"many_to_many.tests.ManyToManyTests.test_add",
116+
"many_to_one.tests.ManyToOneTests.test_fk_assignment_and_related_object_cache",
117+
"model_fields.test_booleanfield.BooleanFieldTests.test_null_default",
118+
"model_fields.test_floatfield.TestFloatField.test_float_validates_object",
119+
"multiple_database.tests.QueryTestCase.test_generic_key_cross_database_protection",
120+
"multiple_database.tests.QueryTestCase.test_m2m_cross_database_protection",
104121
}
105122

106123
@cached_property
@@ -111,6 +128,8 @@ def django_test_expected_failures(self):
111128
expected_failures.update(self._django_test_expected_failures_bitwise)
112129
if self.supports_transactions:
113130
expected_failures.update(self._django_test_expected_failures_transactions)
131+
else:
132+
expected_failures.update(self._django_test_expected_failures_no_transactions)
114133
return expected_failures
115134

116135
django_test_skips = {

django_mongodb_backend/query.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def __repr__(self):
6161
@wrap_database_errors
6262
def delete(self):
6363
"""Execute a delete query."""
64+
self.compiler.connection.validate_no_broken_transaction()
6465
if self.compiler.subqueries:
6566
raise NotSupportedError("Cannot use QuerySet.delete() when a subquery is required.")
6667
return self.compiler.collection.delete_many(
@@ -73,6 +74,7 @@ def get_cursor(self):
7374
Return a pymongo CommandCursor that can be iterated on to give the
7475
results of the query.
7576
"""
77+
self.compiler.connection.validate_no_broken_transaction()
7678
return self.compiler.collection.aggregate(
7779
self.get_pipeline(), session=self.compiler.connection.session
7880
)

0 commit comments

Comments
 (0)