lsst-felis 27.2024.2700__py3-none-any.whl → 27.2024.2800__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.
Potentially problematic release.
This version of lsst-felis might be problematic. Click here for more details.
- felis/datamodel.py +20 -0
- felis/db/sqltypes.py +6 -1
- felis/db/utils.py +1 -1
- felis/metadata.py +34 -6
- felis/version.py +1 -1
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/METADATA +1 -1
- lsst_felis-27.2024.2800.dist-info/RECORD +21 -0
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/WHEEL +1 -1
- lsst_felis-27.2024.2700.dist-info/RECORD +0 -21
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/COPYRIGHT +0 -0
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/LICENSE +0 -0
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/entry_points.txt +0 -0
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/top_level.txt +0 -0
- {lsst_felis-27.2024.2700.dist-info → lsst_felis-27.2024.2800.dist-info}/zip-safe +0 -0
felis/datamodel.py
CHANGED
|
@@ -141,6 +141,13 @@ class Column(BaseObject):
|
|
|
141
141
|
length: int | None = Field(None, gt=0)
|
|
142
142
|
"""Length of the column."""
|
|
143
143
|
|
|
144
|
+
precision: int | None = Field(None, ge=0)
|
|
145
|
+
"""The numerical precision of the column.
|
|
146
|
+
|
|
147
|
+
For timestamps, this is the number of fractional digits retained in the
|
|
148
|
+
seconds field.
|
|
149
|
+
"""
|
|
150
|
+
|
|
144
151
|
nullable: bool = True
|
|
145
152
|
"""Whether the column can be ``NULL``."""
|
|
146
153
|
|
|
@@ -363,6 +370,19 @@ class Column(BaseObject):
|
|
|
363
370
|
)
|
|
364
371
|
return self
|
|
365
372
|
|
|
373
|
+
@model_validator(mode="after")
|
|
374
|
+
def check_precision(self) -> Column:
|
|
375
|
+
"""Check that precision is only valid for timestamp columns.
|
|
376
|
+
|
|
377
|
+
Returns
|
|
378
|
+
-------
|
|
379
|
+
`Column`
|
|
380
|
+
The column being validated.
|
|
381
|
+
"""
|
|
382
|
+
if self.precision is not None and self.datatype != "timestamp":
|
|
383
|
+
raise ValueError("Precision is only valid for timestamp columns")
|
|
384
|
+
return self
|
|
385
|
+
|
|
366
386
|
|
|
367
387
|
class Constraint(BaseObject):
|
|
368
388
|
"""Table constraint model."""
|
felis/db/sqltypes.py
CHANGED
|
@@ -156,6 +156,11 @@ binary_map: _TypeMap = {
|
|
|
156
156
|
POSTGRES: postgresql.BYTEA,
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
timestamp_map: _TypeMap = {
|
|
160
|
+
MYSQL: mysql.DATETIME(timezone=False),
|
|
161
|
+
POSTGRES: postgresql.TIMESTAMP(timezone=False),
|
|
162
|
+
}
|
|
163
|
+
|
|
159
164
|
|
|
160
165
|
def boolean(**kwargs: Any) -> types.TypeEngine:
|
|
161
166
|
"""Get the SQL type for Felis `~felis.types.Boolean` with variants.
|
|
@@ -370,7 +375,7 @@ def timestamp(**kwargs: Any) -> types.TypeEngine:
|
|
|
370
375
|
`~sqlalchemy.types.TypeEngine`
|
|
371
376
|
The SQL type for a Felis timestamp.
|
|
372
377
|
"""
|
|
373
|
-
return types.TIMESTAMP()
|
|
378
|
+
return _vary(types.TIMESTAMP(timezone=False), timestamp_map, kwargs)
|
|
374
379
|
|
|
375
380
|
|
|
376
381
|
def get_type_func(type_name: str) -> Callable:
|
felis/db/utils.py
CHANGED
|
@@ -299,6 +299,6 @@ class DatabaseContext:
|
|
|
299
299
|
The mock connection object.
|
|
300
300
|
"""
|
|
301
301
|
writer = SQLWriter(output_file)
|
|
302
|
-
engine = create_mock_engine(engine_url, executor=writer.write)
|
|
302
|
+
engine = create_mock_engine(engine_url, executor=writer.write, paramstyle="pyformat")
|
|
303
303
|
writer.dialect = engine.dialect
|
|
304
304
|
return engine
|
felis/metadata.py
CHANGED
|
@@ -40,6 +40,7 @@ from sqlalchemy import (
|
|
|
40
40
|
UniqueConstraint,
|
|
41
41
|
text,
|
|
42
42
|
)
|
|
43
|
+
from sqlalchemy.dialects import mysql, postgresql
|
|
43
44
|
from sqlalchemy.types import TypeEngine
|
|
44
45
|
|
|
45
46
|
from felis.datamodel import Schema
|
|
@@ -54,6 +55,28 @@ __all__ = ("MetaDataBuilder", "get_datatype_with_variants")
|
|
|
54
55
|
logger = logging.getLogger(__name__)
|
|
55
56
|
|
|
56
57
|
|
|
58
|
+
def _handle_timestamp_column(column_obj: datamodel.Column, variant_dict: dict[str, TypeEngine[Any]]) -> None:
|
|
59
|
+
"""Handle columns with the timestamp datatype.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
column_obj
|
|
64
|
+
The column object representing the timestamp.
|
|
65
|
+
variant_dict
|
|
66
|
+
The dictionary of variant overrides for the datatype.
|
|
67
|
+
|
|
68
|
+
Notes
|
|
69
|
+
-----
|
|
70
|
+
This function updates the variant dictionary with the appropriate
|
|
71
|
+
timestamp type for the column object but only if the precision is set.
|
|
72
|
+
Otherwise, the default timestamp objects defined in the Felis type system
|
|
73
|
+
will be used instead.
|
|
74
|
+
"""
|
|
75
|
+
if column_obj.precision is not None:
|
|
76
|
+
args: Any = [False, column_obj.precision] # Turn off timezone.
|
|
77
|
+
variant_dict.update({"postgresql": postgresql.TIMESTAMP(*args), "mysql": mysql.DATETIME(*args)})
|
|
78
|
+
|
|
79
|
+
|
|
57
80
|
def get_datatype_with_variants(column_obj: datamodel.Column) -> TypeEngine:
|
|
58
81
|
"""Use the Felis type system to get a SQLAlchemy datatype with variant
|
|
59
82
|
overrides from the information in a Felis column object.
|
|
@@ -71,18 +94,23 @@ def get_datatype_with_variants(column_obj: datamodel.Column) -> TypeEngine:
|
|
|
71
94
|
Raises
|
|
72
95
|
------
|
|
73
96
|
ValueError
|
|
74
|
-
If the column has a sized type but no length
|
|
97
|
+
If the column has a sized type but no length or if the datatype is
|
|
98
|
+
invalid.
|
|
75
99
|
"""
|
|
76
100
|
variant_dict = make_variant_dict(column_obj)
|
|
77
101
|
felis_type = FelisType.felis_type(column_obj.datatype.value)
|
|
78
|
-
datatype_fun = getattr(sqltypes, column_obj.datatype.value)
|
|
102
|
+
datatype_fun = getattr(sqltypes, column_obj.datatype.value, None)
|
|
103
|
+
if datatype_fun is None:
|
|
104
|
+
raise ValueError(f"Unknown datatype: {column_obj.datatype.value}")
|
|
105
|
+
args = []
|
|
79
106
|
if felis_type.is_sized:
|
|
107
|
+
# Add length argument for size types.
|
|
80
108
|
if not column_obj.length:
|
|
81
109
|
raise ValueError(f"Column {column_obj.name} has sized type '{column_obj.datatype}' but no length")
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return
|
|
110
|
+
args = [column_obj.length]
|
|
111
|
+
if felis_type.is_timestamp:
|
|
112
|
+
_handle_timestamp_column(column_obj, variant_dict)
|
|
113
|
+
return datatype_fun(*args, **variant_dict)
|
|
86
114
|
|
|
87
115
|
|
|
88
116
|
_VALID_SERVER_DEFAULTS = ("CURRENT_TIMESTAMP", "NOW()", "LOCALTIMESTAMP", "NULL")
|
felis/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "27.2024.
|
|
2
|
+
__version__ = "27.2024.2800"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lsst-felis
|
|
3
|
-
Version: 27.2024.
|
|
3
|
+
Version: 27.2024.2800
|
|
4
4
|
Summary: A vocabulary for describing catalogs and acting on those descriptions
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License: GNU General Public License v3 or later (GPLv3+)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
felis/__init__.py,sha256=THmRg3ylB4E73XhFjJX7YlnV_CM3lr_gZO_HqQFzIQ4,937
|
|
2
|
+
felis/cli.py,sha256=i5FlA9OBecqHP4SISngaveQ7YbWH8pxRGHeOzMOOMyg,14086
|
|
3
|
+
felis/datamodel.py,sha256=BajYwp2rk0j3P4KSc2T9Acnk9p9pjzXiKgZG2c_OuZI,26517
|
|
4
|
+
felis/metadata.py,sha256=8r2LM86kdJLSuI0_t--oE3OtRPf-s5aH3FeIDDDAPZ8,13414
|
|
5
|
+
felis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
felis/tap.py,sha256=YBWl1CicdN4jW_KhPJQ7-TuhOfFFTIYIH4tTJ8P_o1c,21035
|
|
7
|
+
felis/types.py,sha256=m80GSGfNHQ3-NzRuTzKOyRXLJboPxdk9kzpp1SO8XdY,5510
|
|
8
|
+
felis/version.py,sha256=yUl4M-EIGpU6iDSDVfXNp4Wf1kDc1_9Neo9VCBg7Ph8,55
|
|
9
|
+
felis/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
felis/db/dialects.py,sha256=IsjdD_2n7tucUdR7TMyRd2gWtnD-2kXPAJUUQdbUe_Q,3526
|
|
11
|
+
felis/db/sqltypes.py,sha256=VuBfstnBGOnr0RuSN0XhzXjSr2MaAmgJWuiWuf_7g2A,11418
|
|
12
|
+
felis/db/utils.py,sha256=_vWVsPsq_kVl-WQuDeoLY3ZxElGCCEzPp3tfBTENGB8,10200
|
|
13
|
+
felis/db/variants.py,sha256=o5m101upQQbWZD_l8qlB8gt-ZQ9-VqsWZrmxQO1eEQA,5246
|
|
14
|
+
lsst_felis-27.2024.2800.dist-info/COPYRIGHT,sha256=vJAFLFTSF1mhy9eIuA3P6R-3yxTWKQgpig88P-1IzRw,129
|
|
15
|
+
lsst_felis-27.2024.2800.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
16
|
+
lsst_felis-27.2024.2800.dist-info/METADATA,sha256=B5KUETflTJuITLE5h9ljJ6aDsA9mtlHemnxJfi7StW4,1288
|
|
17
|
+
lsst_felis-27.2024.2800.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
18
|
+
lsst_felis-27.2024.2800.dist-info/entry_points.txt,sha256=Gk2XFujA_Gp52VBk45g5kim8TDoMDJFPctsMqiq72EM,40
|
|
19
|
+
lsst_felis-27.2024.2800.dist-info/top_level.txt,sha256=F4SvPip3iZRVyISi50CHhwTIAokAhSxjWiVcn4IVWRI,6
|
|
20
|
+
lsst_felis-27.2024.2800.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
21
|
+
lsst_felis-27.2024.2800.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
felis/__init__.py,sha256=THmRg3ylB4E73XhFjJX7YlnV_CM3lr_gZO_HqQFzIQ4,937
|
|
2
|
-
felis/cli.py,sha256=i5FlA9OBecqHP4SISngaveQ7YbWH8pxRGHeOzMOOMyg,14086
|
|
3
|
-
felis/datamodel.py,sha256=k0wAZpIhwOWVvAlHLLpzCOYYxY5iD8jpjlOu_lpzv-4,25902
|
|
4
|
-
felis/metadata.py,sha256=W1Y4s7izAEiH3MLJkKQpvxHsGE5Dbu4lhhNCzWlfl0o,12290
|
|
5
|
-
felis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
felis/tap.py,sha256=YBWl1CicdN4jW_KhPJQ7-TuhOfFFTIYIH4tTJ8P_o1c,21035
|
|
7
|
-
felis/types.py,sha256=m80GSGfNHQ3-NzRuTzKOyRXLJboPxdk9kzpp1SO8XdY,5510
|
|
8
|
-
felis/version.py,sha256=Py-EC2UdOs7tbGMklTl45bEVHW1tbRLsn35DytqzMs0,55
|
|
9
|
-
felis/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
felis/db/dialects.py,sha256=IsjdD_2n7tucUdR7TMyRd2gWtnD-2kXPAJUUQdbUe_Q,3526
|
|
11
|
-
felis/db/sqltypes.py,sha256=sDzkqemYwILp8hk0yfg3H0ZK7bGnIJR9x6ntd2coASc,11248
|
|
12
|
-
felis/db/utils.py,sha256=TgNJTBv2Jt4Qq_RtOO_jWj_02tb-fEA2QeOOHYS1GyU,10177
|
|
13
|
-
felis/db/variants.py,sha256=o5m101upQQbWZD_l8qlB8gt-ZQ9-VqsWZrmxQO1eEQA,5246
|
|
14
|
-
lsst_felis-27.2024.2700.dist-info/COPYRIGHT,sha256=vJAFLFTSF1mhy9eIuA3P6R-3yxTWKQgpig88P-1IzRw,129
|
|
15
|
-
lsst_felis-27.2024.2700.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
16
|
-
lsst_felis-27.2024.2700.dist-info/METADATA,sha256=A5aJVx9iUOUBeR4Lxwqzpct3I1A3krP13BWPc3zMbpE,1288
|
|
17
|
-
lsst_felis-27.2024.2700.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
18
|
-
lsst_felis-27.2024.2700.dist-info/entry_points.txt,sha256=Gk2XFujA_Gp52VBk45g5kim8TDoMDJFPctsMqiq72EM,40
|
|
19
|
-
lsst_felis-27.2024.2700.dist-info/top_level.txt,sha256=F4SvPip3iZRVyISi50CHhwTIAokAhSxjWiVcn4IVWRI,6
|
|
20
|
-
lsst_felis-27.2024.2700.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
21
|
-
lsst_felis-27.2024.2700.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|