GeneralManager 0.20.0__tar.gz → 0.20.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of GeneralManager might be problematic. Click here for more details.
- {generalmanager-0.20.0/src/GeneralManager.egg-info → generalmanager-0.20.1}/PKG-INFO +1 -1
- {generalmanager-0.20.0 → generalmanager-0.20.1}/pyproject.toml +1 -1
- {generalmanager-0.20.0 → generalmanager-0.20.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/read_only_interface.py +31 -14
- {generalmanager-0.20.0 → generalmanager-0.20.1}/LICENSE +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/README.md +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/setup.cfg +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/apps.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/calculation_interface.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/database_based_interface.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/database_interface.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/models.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/logging.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/file_based_permission.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/py.typed +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/make_cache_key.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/none_to_zero.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/tests/test_settings.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/tests/test_urls.py +0 -0
- {generalmanager-0.20.0 → generalmanager-0.20.1}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.20.
|
|
7
|
+
version = "0.20.1"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/read_only_interface.py
RENAMED
|
@@ -6,7 +6,7 @@ import json
|
|
|
6
6
|
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Type, cast
|
|
7
7
|
|
|
8
8
|
from django.core.checks import Warning
|
|
9
|
-
from django.db import connection, models, transaction
|
|
9
|
+
from django.db import connection, models, transaction, IntegrityError
|
|
10
10
|
|
|
11
11
|
from general_manager.interface.database_based_interface import (
|
|
12
12
|
DBBasedInterface,
|
|
@@ -159,6 +159,7 @@ class ReadOnlyInterface(DBBasedInterface[GeneralManagerBasisModel]):
|
|
|
159
159
|
data_list = cast(list[dict[str, Any]], parsed_data)
|
|
160
160
|
|
|
161
161
|
unique_fields = cls.get_unique_fields(model)
|
|
162
|
+
unique_field_order = tuple(sorted(unique_fields))
|
|
162
163
|
if not unique_fields:
|
|
163
164
|
raise MissingUniqueFieldError(parent_class.__name__)
|
|
164
165
|
|
|
@@ -168,29 +169,43 @@ class ReadOnlyInterface(DBBasedInterface[GeneralManagerBasisModel]):
|
|
|
168
169
|
"deactivated": [],
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
editable_fields = {
|
|
173
|
+
f.name
|
|
174
|
+
for f in model._meta.local_fields
|
|
175
|
+
if getattr(f, "editable", True) and not getattr(f, "primary_key", False)
|
|
176
|
+
} - {"is_active"}
|
|
177
|
+
|
|
171
178
|
with transaction.atomic():
|
|
172
|
-
json_unique_values: set[Any] = set()
|
|
179
|
+
json_unique_values: set[tuple[Any, ...]] = set()
|
|
173
180
|
|
|
174
181
|
# data synchronization
|
|
175
182
|
for idx, data in enumerate(data_list):
|
|
176
183
|
try:
|
|
177
|
-
lookup = {field: data[field] for field in
|
|
184
|
+
lookup = {field: data[field] for field in unique_field_order}
|
|
178
185
|
except KeyError as e:
|
|
179
186
|
missing = e.args[0]
|
|
180
187
|
raise InvalidReadOnlyDataFormatError() from KeyError(
|
|
181
188
|
f"Item {idx} missing unique field '{missing}'."
|
|
182
189
|
)
|
|
183
|
-
unique_identifier = tuple(lookup[field] for field in
|
|
190
|
+
unique_identifier = tuple(lookup[field] for field in unique_field_order)
|
|
184
191
|
json_unique_values.add(unique_identifier)
|
|
185
|
-
|
|
186
|
-
|
|
192
|
+
instance = model.objects.filter(**lookup).first()
|
|
193
|
+
is_created = False
|
|
194
|
+
if instance is None:
|
|
195
|
+
# sanitize input and create with race-safety
|
|
196
|
+
allowed_fields = {f.name for f in model._meta.local_fields}
|
|
197
|
+
create_kwargs = {
|
|
198
|
+
k: v for k, v in data.items() if k in allowed_fields
|
|
199
|
+
}
|
|
200
|
+
try:
|
|
201
|
+
instance = model.objects.create(**create_kwargs)
|
|
202
|
+
is_created = True
|
|
203
|
+
except IntegrityError:
|
|
204
|
+
# created concurrently — fetch it
|
|
205
|
+
instance = model.objects.filter(**lookup).first()
|
|
206
|
+
if instance is None:
|
|
207
|
+
raise
|
|
187
208
|
updated = False
|
|
188
|
-
editable_fields = {
|
|
189
|
-
f.name
|
|
190
|
-
for f in model._meta.local_fields
|
|
191
|
-
if getattr(f, "editable", True)
|
|
192
|
-
and not getattr(f, "primary_key", False)
|
|
193
|
-
} - {"is_active"}
|
|
194
209
|
for field_name in editable_fields.intersection(data.keys()):
|
|
195
210
|
value = data[field_name]
|
|
196
211
|
if getattr(instance, field_name, None) != value:
|
|
@@ -204,8 +219,10 @@ class ReadOnlyInterface(DBBasedInterface[GeneralManagerBasisModel]):
|
|
|
204
219
|
# deactivate instances not in JSON data
|
|
205
220
|
existing_instances = model.objects.filter(is_active=True)
|
|
206
221
|
for instance in existing_instances:
|
|
207
|
-
lookup = {
|
|
208
|
-
|
|
222
|
+
lookup = {
|
|
223
|
+
field: getattr(instance, field) for field in unique_field_order
|
|
224
|
+
}
|
|
225
|
+
unique_identifier = tuple(lookup[field] for field in unique_field_order)
|
|
209
226
|
if unique_identifier not in json_unique_values:
|
|
210
227
|
instance.is_active = False
|
|
211
228
|
instance.save()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/GeneralManager.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/_types/general_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/calculation_bucket.py
RENAMED
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/bucket/database_bucket.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/cache_decorator.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/cache/dependency_index.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/factory/factory_methods.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/base_interface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/interface/database_interface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/general_manager.py
RENAMED
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/manager/group_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/measurement/measurement.py
RENAMED
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/measurement/measurement_field.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/base_permission.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.20.0 → generalmanager-0.20.1}/src/general_manager/permission/permission_checks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|