Skip to content

Commit 5a9f61c

Browse files
committed
Add write concern support for issue #6
- Add WriteConcern import from pymongo - Add write concern parsing in DatabaseWrapper.__init__() - Support dict, string, and int write concern formats - Apply write concern to collections in get_collection() - Add comprehensive tests for write concern functionality
1 parent 84c8299 commit 5a9f61c

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

django_mongodb_backend/base.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from pymongo.collection import Collection
1111
from pymongo.driver_info import DriverInfo
1212
from pymongo.mongo_client import MongoClient
13+
from pymongo.write_concern import WriteConcern
1314

1415
from . import __version__ as django_mongodb_backend_version
1516
from . import dbapi as Database
@@ -156,8 +157,29 @@ def _isnull_operator(a, b):
156157
def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS):
157158
super().__init__(settings_dict, alias=alias)
158159
self.session = None
160+
self._write_concern = self._parse_write_concern(settings_dict.get('OPTIONS', {}).get('WRITE_CONCERN'))
161+
162+
def _parse_write_concern(self, write_concern_config):
163+
"""Parse write concern configuration from Django settings."""
164+
if write_concern_config is None:
165+
return None
166+
167+
if isinstance(write_concern_config, dict):
168+
return WriteConcern(**write_concern_config)
169+
elif isinstance(write_concern_config, str):
170+
return WriteConcern(w=write_concern_config)
171+
elif isinstance(write_concern_config, int):
172+
return WriteConcern(w=write_concern_config)
173+
else:
174+
raise ImproperlyConfigured(
175+
f"WRITE_CONCERN must be a dict, str, or int, got {type(write_concern_config)}"
176+
)
159177

160178
def get_collection(self, name, **kwargs):
179+
# Apply write concern if configured
180+
if self._write_concern is not None:
181+
kwargs.setdefault('write_concern', self._write_concern)
182+
161183
collection = Collection(self.database, name, **kwargs)
162184
if self.queries_logged:
163185
collection = OperationDebugWrapper(self, collection)

tests/backend_/test_write_concern.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from django.core.exceptions import ImproperlyConfigured
2+
from django.test import TestCase
3+
from pymongo.write_concern import WriteConcern
4+
5+
from django_mongodb_backend.base import DatabaseWrapper
6+
7+
8+
class WriteConcerrTests(TestCase):
9+
def test_parse_write_concern_dict(self):
10+
"""Test parsing write concern from dictionary configuration."""
11+
settings_dict = {
12+
'NAME': 'test_db',
13+
'OPTIONS': {
14+
'WRITE_CONCERN': {'w': 'majority', 'j': True, 'wtimeout': 5000}
15+
}
16+
}
17+
wrapper = DatabaseWrapper(settings_dict)
18+
19+
self.assertIsInstance(wrapper._write_concern, WriteConcern)
20+
self.assertIsNotNone(wrapper._write_concern)
21+
self.assertEqual(wrapper._write_concern.document['w'], 'majority')
22+
self.assertEqual(wrapper._write_concern.document['j'], True)
23+
self.assertEqual(wrapper._write_concern.document['wtimeout'], 5000)
24+
25+
def test_parse_write_concern_string(self):
26+
"""Test parsing write concern from string configuration."""
27+
settings_dict = {
28+
'NAME': 'test_db',
29+
'OPTIONS': {
30+
'WRITE_CONCERN': 'majority'
31+
}
32+
}
33+
wrapper = DatabaseWrapper(settings_dict)
34+
35+
self.assertIsInstance(wrapper._write_concern, WriteConcern)
36+
self.assertIsNotNone(wrapper._write_concern)
37+
self.assertEqual(wrapper._write_concern.document['w'], 'majority')
38+
39+
def test_parse_write_concern_int(self):
40+
"""Test parsing write concern from integer configuration."""
41+
settings_dict = {
42+
'NAME': 'test_db',
43+
'OPTIONS': {
44+
'WRITE_CONCERN': 2
45+
}
46+
}
47+
wrapper = DatabaseWrapper(settings_dict)
48+
49+
self.assertIsInstance(wrapper._write_concern, WriteConcern)
50+
self.assertIsNotNone(wrapper._write_concern)
51+
self.assertEqual(wrapper._write_concern.document['w'], 2)
52+
53+
def test_parse_write_concern_none(self):
54+
"""Test that None write concern config results in None."""
55+
settings_dict = {
56+
'NAME': 'test_db',
57+
'OPTIONS': {}
58+
}
59+
wrapper = DatabaseWrapper(settings_dict)
60+
61+
self.assertIsNone(wrapper._write_concern)
62+
63+
def test_parse_write_concern_invalid_type(self):
64+
"""Test that invalid write concern type raises ImproperlyConfigured."""
65+
settings_dict = {
66+
'NAME': 'test_db',
67+
'OPTIONS': {
68+
'WRITE_CONCERN': ['invalid', 'type']
69+
}
70+
}
71+
72+
with self.assertRaises(ImproperlyConfigured):
73+
DatabaseWrapper(settings_dict)

0 commit comments

Comments
 (0)