lsst-felis 28.2024.4500__py3-none-any.whl → 30.0.0rc3__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.
- felis/__init__.py +9 -1
- felis/cli.py +308 -209
- felis/config/tap_schema/columns.csv +33 -0
- felis/config/tap_schema/key_columns.csv +8 -0
- felis/config/tap_schema/keys.csv +8 -0
- felis/config/tap_schema/schemas.csv +2 -0
- felis/config/tap_schema/tables.csv +6 -0
- felis/config/tap_schema/tap_schema_extensions.yaml +73 -0
- felis/datamodel.py +599 -59
- felis/db/{dialects.py → _dialects.py} +69 -4
- felis/db/{variants.py → _variants.py} +1 -1
- felis/db/database_context.py +917 -0
- felis/diff.py +234 -0
- felis/metadata.py +89 -19
- felis/tap_schema.py +271 -166
- felis/tests/postgresql.py +1 -1
- felis/tests/run_cli.py +79 -0
- felis/types.py +7 -7
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info}/METADATA +20 -16
- lsst_felis-30.0.0rc3.dist-info/RECORD +31 -0
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info}/WHEEL +1 -1
- felis/db/utils.py +0 -409
- felis/tap.py +0 -597
- felis/tests/utils.py +0 -122
- felis/version.py +0 -2
- lsst_felis-28.2024.4500.dist-info/RECORD +0 -26
- felis/{schemas → config/tap_schema}/tap_schema_std.yaml +0 -0
- felis/db/{sqltypes.py → _sqltypes.py} +7 -7
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info}/entry_points.txt +0 -0
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info/licenses}/COPYRIGHT +0 -0
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info/licenses}/LICENSE +0 -0
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info}/top_level.txt +0 -0
- {lsst_felis-28.2024.4500.dist-info → lsst_felis-30.0.0rc3.dist-info}/zip-safe +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Utilities for accessing SQLAlchemy dialects and their type modules."""
|
|
2
2
|
|
|
3
3
|
# This file is part of felis.
|
|
4
4
|
#
|
|
@@ -23,16 +23,18 @@
|
|
|
23
23
|
|
|
24
24
|
from __future__ import annotations
|
|
25
25
|
|
|
26
|
+
import re
|
|
26
27
|
from collections.abc import Mapping
|
|
27
28
|
from types import MappingProxyType, ModuleType
|
|
28
29
|
|
|
29
|
-
from sqlalchemy import dialects
|
|
30
|
+
from sqlalchemy import dialects, types
|
|
30
31
|
from sqlalchemy.engine import Dialect
|
|
31
32
|
from sqlalchemy.engine.mock import create_mock_engine
|
|
33
|
+
from sqlalchemy.types import TypeEngine
|
|
32
34
|
|
|
33
|
-
from .
|
|
35
|
+
from ._sqltypes import MYSQL, POSTGRES, SQLITE
|
|
34
36
|
|
|
35
|
-
__all__ = ["get_supported_dialects", "
|
|
37
|
+
__all__ = ["get_dialect_module", "get_supported_dialects", "string_to_typeengine"]
|
|
36
38
|
|
|
37
39
|
_DIALECT_NAMES = (MYSQL, POSTGRES, SQLITE)
|
|
38
40
|
"""List of supported dialect names.
|
|
@@ -40,6 +42,9 @@ _DIALECT_NAMES = (MYSQL, POSTGRES, SQLITE)
|
|
|
40
42
|
This list is used to create the dialect and module dictionaries.
|
|
41
43
|
"""
|
|
42
44
|
|
|
45
|
+
_DATATYPE_REGEXP = re.compile(r"(\w+)(\((.*)\))?")
|
|
46
|
+
"""Regular expression to match data types with parameters in parentheses."""
|
|
47
|
+
|
|
43
48
|
|
|
44
49
|
def _dialect(dialect_name: str) -> Dialect:
|
|
45
50
|
"""Create the SQLAlchemy dialect for the given name using a mock engine.
|
|
@@ -114,3 +119,63 @@ def get_dialect_module(dialect_name: str) -> ModuleType:
|
|
|
114
119
|
if dialect_name not in _DIALECT_MODULES:
|
|
115
120
|
raise ValueError(f"Unsupported dialect: {dialect_name}")
|
|
116
121
|
return _DIALECT_MODULES[dialect_name]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def string_to_typeengine(
|
|
125
|
+
type_string: str, dialect: Dialect | None = None, length: int | None = None
|
|
126
|
+
) -> TypeEngine:
|
|
127
|
+
"""Convert a string representation of a datatype to a SQLAlchemy type.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
type_string
|
|
132
|
+
The string representation of the data type.
|
|
133
|
+
dialect
|
|
134
|
+
The SQLAlchemy dialect to use. If None, the default dialect will be
|
|
135
|
+
used.
|
|
136
|
+
length
|
|
137
|
+
The length of the data type. If the data type does not have a length
|
|
138
|
+
attribute, this parameter will be ignored.
|
|
139
|
+
|
|
140
|
+
Returns
|
|
141
|
+
-------
|
|
142
|
+
`sqlalchemy.types.TypeEngine`
|
|
143
|
+
The SQLAlchemy type engine object.
|
|
144
|
+
|
|
145
|
+
Raises
|
|
146
|
+
------
|
|
147
|
+
ValueError
|
|
148
|
+
Raised if the type string is invalid or the type is not supported.
|
|
149
|
+
|
|
150
|
+
Notes
|
|
151
|
+
-----
|
|
152
|
+
This function is used when converting type override strings defined in
|
|
153
|
+
fields such as ``mysql:datatype`` in the schema data.
|
|
154
|
+
"""
|
|
155
|
+
match = _DATATYPE_REGEXP.search(type_string)
|
|
156
|
+
if not match:
|
|
157
|
+
raise ValueError(f"Invalid type string: {type_string}")
|
|
158
|
+
|
|
159
|
+
type_name, _, params = match.groups()
|
|
160
|
+
if dialect is None:
|
|
161
|
+
type_class = getattr(types, type_name.upper(), None)
|
|
162
|
+
else:
|
|
163
|
+
try:
|
|
164
|
+
dialect_module = get_dialect_module(dialect.name)
|
|
165
|
+
except KeyError:
|
|
166
|
+
raise ValueError(f"Unsupported dialect: {dialect}")
|
|
167
|
+
type_class = getattr(dialect_module, type_name.upper(), None)
|
|
168
|
+
|
|
169
|
+
if not type_class:
|
|
170
|
+
raise ValueError(f"Unsupported type: {type_name.upper()}")
|
|
171
|
+
|
|
172
|
+
if params:
|
|
173
|
+
params = [int(param) if param.isdigit() else param for param in params.split(",")]
|
|
174
|
+
type_obj = type_class(*params)
|
|
175
|
+
else:
|
|
176
|
+
type_obj = type_class()
|
|
177
|
+
|
|
178
|
+
if hasattr(type_obj, "length") and getattr(type_obj, "length") is None and length is not None:
|
|
179
|
+
type_obj.length = length
|
|
180
|
+
|
|
181
|
+
return type_obj
|
|
@@ -32,7 +32,7 @@ from sqlalchemy import types
|
|
|
32
32
|
from sqlalchemy.types import TypeEngine
|
|
33
33
|
|
|
34
34
|
from ..datamodel import Column
|
|
35
|
-
from .
|
|
35
|
+
from ._dialects import get_dialect_module, get_supported_dialects
|
|
36
36
|
|
|
37
37
|
__all__ = ["make_variant_dict"]
|
|
38
38
|
|