Skip to content

Commit 68ba497

Browse files
authored
Merge pull request #212 from poissoncorp/RDBC-815
RDBC-815 Make storing dictionaries as collection documents work properly
2 parents a2f85f2 + c73d943 commit 68ba497

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

ravendb/documents/conventions.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def default_conventions(cls):
3232
return cls()
3333

3434
__cached_default_type_collection_names: Dict[type, str] = {}
35+
__cached_keys_collection_names: Dict[str, str] = {}
3536

3637
def __init__(self):
3738
self._frozen = False
@@ -65,6 +66,7 @@ def __init__(self):
6566
self._find_identity_property = lambda q: q.__name__ == "key"
6667
self._find_python_class: Optional[Callable[[str, Dict], str]] = None
6768
self._find_collection_name: Callable[[Type], str] = self.default_get_collection_name
69+
self._find_collection_name_for_dict: Callable[[str], str] = self.default_get_collection_name_for_dict
6870
self._find_python_class_name: Callable[[Type], str] = (
6971
lambda object_type: f"{object_type.__module__}.{object_type.__name__}"
7072
)
@@ -281,6 +283,13 @@ def get_collection_name(self, entity_or_type: Union[type, object]) -> str:
281283

282284
return self.default_get_collection_name(object_type)
283285

286+
def get_collection_name_for_dict(self, key: str):
287+
collection = key.split("/")[0]
288+
collection_name = self._find_collection_name_for_dict(collection)
289+
if collection_name:
290+
return collection_name
291+
return self.default_get_collection_name(dict)
292+
284293
def generate_document_id(self, database_name: str, entity: object) -> str:
285294
object_type = type(entity)
286295
for list_of_registered_id_convention in self._list_of_registered_id_conventions:
@@ -305,6 +314,16 @@ def default_get_collection_name(object_type: type) -> str:
305314
DocumentConventions.__cached_default_type_collection_names[object_type] = result
306315
return result
307316

317+
@staticmethod
318+
def default_get_collection_name_for_dict(key: str) -> str:
319+
result = DocumentConventions.__cached_keys_collection_names.get(key, None)
320+
if result:
321+
return result
322+
# singular_noun returns False if the word is singular
323+
result = inflector.plural(key) if not inflector.singular_noun(key) else key
324+
DocumentConventions.__cached_keys_collection_names[key] = result
325+
return result
326+
308327
@staticmethod
309328
def try_get_type_from_metadata(metadata):
310329
if "Raven-Python-Type" in metadata:

ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,12 @@ def __store_internal(
907907

908908
self._assert_no_non_unique_instance(entity, key)
909909

910-
collection_name = self._request_executor.conventions.get_collection_name(entity)
910+
collection_name = (
911+
self.conventions.get_collection_name_for_dict(key)
912+
if entity.__class__ is dict and key and len(key.split("/")) > 1
913+
else self._request_executor.conventions.get_collection_name(entity)
914+
)
915+
911916
metadata = {}
912917
if collection_name:
913918
metadata[constants.Documents.Metadata.COLLECTION] = collection_name
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from ravendb.tests.test_base import TestBase
2+
3+
4+
class TestRDBC815(TestBase):
5+
def setUp(self):
6+
super().setUp()
7+
8+
def test_dict_into_collection(self):
9+
with self.store.open_session() as session:
10+
session.store({"name": "Gracjan"}, "Drivers/")
11+
session.save_changes()
12+
13+
with self.store.open_session() as session:
14+
drivers = list(session.query_collection("Drivers"))
15+
self.assertEqual(1, len(drivers))
16+
self.assertEqual("Gracjan", drivers[0]["name"])

0 commit comments

Comments
 (0)