spinta 0.2.dev17__py3-none-any.whl → 0.2.dev19__py3-none-any.whl

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.
spinta/__init__.py CHANGED
@@ -1,3 +1,5 @@
1
1
  import importlib.metadata
2
2
 
3
3
  __version__ = importlib.metadata.version(__name__)
4
+
5
+ HTTP_URL_PREFIXES = ("http://", "https://")
@@ -6,7 +6,7 @@ from spinta.backends.helpers import get_table_name
6
6
  from spinta.backends.postgresql.helpers.name import get_pg_table_name, get_pg_column_name
7
7
  from spinta.core.ufuncs import Expr
8
8
  from spinta.types.datatype import Integer, Number, Boolean, String, Date, DateTime, Time, Ref
9
- from spinta import commands
9
+ from spinta import commands, HTTP_URL_PREFIXES
10
10
  from spinta.components import Context, Property
11
11
  from spinta.components import Model
12
12
  from spinta.exceptions import NotFoundError, NotImplementedFeature, InvalidRequestQuery
@@ -322,7 +322,7 @@ def summary(context: Context, dtype: Ref, backend: PostgreSQL, **kwargs):
322
322
  prefixes = dtype.model.external.dataset.prefixes
323
323
  label = None
324
324
  if uri and ":" in uri:
325
- if uri.startswith(("http://", "https://")):
325
+ if uri.startswith(HTTP_URL_PREFIXES):
326
326
  label = uri
327
327
  else:
328
328
  split = uri.split(":")
@@ -15,7 +15,7 @@ from spinta.datasets.backends.dataframe.ufuncs.query.components import (
15
15
  )
16
16
  from spinta.datasets.components import Param
17
17
  from spinta.datasets.utils import iterparams
18
- from spinta.exceptions import PropertyNotFound, NotImplementedFeature, SourceCannotBeList
18
+ from spinta.exceptions import PropertyNotFound, NotImplementedFeature, SourceCannotBeList, SourceOrPrepareNotAllowed
19
19
  from spinta.types.datatype import DataType, PrimaryKey, Ref
20
20
  from spinta.types.text.components import Text
21
21
  from spinta.ufuncs.components import ForeignProperty
@@ -188,9 +188,12 @@ def select(env: DaskDataFrameQueryBuilder, prop: Property) -> Selected:
188
188
  # tag:resolving_private_properties_in_prepare_context
189
189
  result = env.call("select", prop.dtype, result)
190
190
  elif prop.external.prepare is not NA:
191
- # property without external name and with `prepare` is already evaluated
192
- # so just use evaluated value
193
- result = Selected(prop=prop, prep=prop.external.prepare)
191
+ # property without external name may be evaluated already, if it is use the value
192
+ if isinstance(prop.external.prepare, Expr):
193
+ result = env(this=prop).resolve(prop.external.prepare)
194
+ result = env.call("select", prop.dtype, result)
195
+ else:
196
+ result = Selected(prop=prop, prep=prop.external.prepare)
194
197
  elif prop.external and prop.external.name:
195
198
  # If prepare is not given, then take value from `source`.
196
199
  result = env.call("select", prop.dtype)
@@ -339,7 +342,7 @@ def select(
339
342
  ) -> Selected:
340
343
  # TODO need join for this to work
341
344
  return Selected(
342
- item=dtype.prop.name,
345
+ item=dtype.prop.external.name,
343
346
  prop=dtype.prop,
344
347
  )
345
348
 
@@ -458,3 +461,13 @@ def eval_(env: DaskDataFrameQueryBuilder, param: Param) -> Iterator[str]:
458
461
  )
459
462
 
460
463
  return resolved_values
464
+
465
+
466
+ @ufunc.resolver(DaskDataFrameQueryBuilder, Bind, Bind, name="getattr")
467
+ def getattr_(env: DaskDataFrameQueryBuilder, obj: Bind, attr: Bind) -> Any:
468
+ return GetAttr(obj, attr)
469
+
470
+
471
+ @ufunc.resolver(DaskDataFrameQueryBuilder, Bind, Bind, Bind, name="getattr")
472
+ def getattr_(env: DaskDataFrameQueryBuilder, source: Bind, obj: Bind, attr: Bind) -> Any:
473
+ raise SourceOrPrepareNotAllowed(source=str(source))
spinta/exceptions.py CHANGED
@@ -1215,3 +1215,9 @@ class EnumPrepareMissing(UserError):
1215
1215
  template = """
1216
1216
  Enum {enum} is missing a required value in the prepare column.
1217
1217
  """
1218
+
1219
+
1220
+ class SourceOrPrepareNotAllowed(UserError):
1221
+ template = """
1222
+ The source {source} was not expected. Delete it from the manifest or update the prepare function to allow it.
1223
+ """
@@ -1,7 +1,8 @@
1
+ import dataclasses
1
2
  from enum import Enum
2
3
 
3
-
4
4
  from spinta.manifests.components import Manifest
5
+ from spinta.manifests.helpers import TypeDetector
5
6
 
6
7
 
7
8
  class DictFormat(Enum):
@@ -30,3 +31,103 @@ class XmlManifest(DictManifest):
30
31
  @staticmethod
31
32
  def detect_from_path(path: str) -> bool:
32
33
  return path.endswith(".xml")
34
+
35
+
36
+ @dataclasses.dataclass
37
+ class _MappedProperties:
38
+ name: str
39
+ source: str
40
+ extra: str
41
+ type_detector: TypeDetector
42
+
43
+
44
+ @dataclasses.dataclass
45
+ class _MappedModels:
46
+ name: str
47
+ source: str
48
+ properties: dict[str, _MappedProperties]
49
+
50
+
51
+ @dataclasses.dataclass
52
+ class _MappedDataset:
53
+ dataset: str
54
+ resource: str
55
+ models: dict[str, dict[str, _MappedModels]]
56
+
57
+
58
+ @dataclasses.dataclass
59
+ class _MappingMeta:
60
+ is_blank_node: bool
61
+ blank_node_name: str
62
+ blank_node_source: str
63
+ seperator: str
64
+ recursive_descent: str
65
+ remove_array_suffix: bool
66
+ model_source_prefix: str
67
+ check_namespace: bool
68
+ namespace_prefixes: dict[str, list[str]]
69
+ namespace_seperator: str
70
+
71
+ @classmethod
72
+ def get_for(cls, manifest_type: DictFormat) -> "_MappingMeta":
73
+ if manifest_type == DictFormat.JSON:
74
+ mapping_meta = _MappingMeta.for_json()
75
+ elif manifest_type in (DictFormat.XML, DictFormat.HTML):
76
+ mapping_meta = _MappingMeta.for_xml()
77
+ else:
78
+ mapping_meta = _MappingMeta.default()
79
+
80
+ return mapping_meta
81
+
82
+ @classmethod
83
+ def for_json(cls) -> "_MappingMeta":
84
+ return cls(
85
+ is_blank_node=False,
86
+ blank_node_name="model1",
87
+ blank_node_source=".",
88
+ seperator=".",
89
+ recursive_descent=".",
90
+ model_source_prefix="",
91
+ namespace_seperator=":",
92
+ remove_array_suffix=False,
93
+ check_namespace=False,
94
+ namespace_prefixes={},
95
+ )
96
+
97
+ @classmethod
98
+ def for_xml(cls) -> "_MappingMeta":
99
+ return cls(
100
+ is_blank_node=False,
101
+ blank_node_name="model1",
102
+ blank_node_source=".",
103
+ seperator="/",
104
+ recursive_descent="/..",
105
+ model_source_prefix="/",
106
+ namespace_seperator=":",
107
+ remove_array_suffix=True,
108
+ check_namespace=True,
109
+ namespace_prefixes={"xmlns": ["xmlns", "@xmlns"]},
110
+ )
111
+
112
+ @classmethod
113
+ def default(cls) -> "_MappingMeta":
114
+ return cls(
115
+ is_blank_node=False,
116
+ blank_node_name="model1",
117
+ blank_node_source=".",
118
+ seperator="",
119
+ recursive_descent="",
120
+ model_source_prefix="",
121
+ namespace_seperator=":",
122
+ remove_array_suffix=False,
123
+ check_namespace=False,
124
+ namespace_prefixes={},
125
+ )
126
+
127
+
128
+ @dataclasses.dataclass
129
+ class _MappingScope:
130
+ parent_scope: str
131
+ model_scope: str
132
+ model_name: str
133
+ property_name: str