lsst-felis 29.2025.2500__tar.gz → 29.2025.2600__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 lsst-felis might be problematic. Click here for more details.
- {lsst_felis-29.2025.2500/python/lsst_felis.egg-info → lsst_felis-29.2025.2600}/PKG-INFO +1 -1
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/datamodel.py +182 -19
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600/python/lsst_felis.egg-info}/PKG-INFO +1 -1
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_datamodel.py +101 -2
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/COPYRIGHT +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/LICENSE +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/README.rst +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/pyproject.toml +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/__init__.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/cli.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/columns.csv +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/key_columns.csv +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/keys.csv +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/schemas.csv +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/tables.csv +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/tap_schema_std.yaml +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/db/__init__.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/db/dialects.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/db/schema.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/db/sqltypes.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/db/utils.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/db/variants.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/diff.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/metadata.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/py.typed +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/tap_schema.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/tests/__init__.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/tests/postgresql.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/tests/run_cli.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/types.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/SOURCES.txt +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/dependency_links.txt +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/entry_points.txt +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/requires.txt +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/top_level.txt +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/zip-safe +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/setup.cfg +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_cli.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_db.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_diff.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_metadata.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_postgres.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_tap_schema.py +0 -0
- {lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/tests/test_tap_schema_postgres.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-felis
|
|
3
|
-
Version: 29.2025.
|
|
3
|
+
Version: 29.2025.2600
|
|
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+)
|
|
@@ -39,11 +39,13 @@ from pydantic import (
|
|
|
39
39
|
ConfigDict,
|
|
40
40
|
Field,
|
|
41
41
|
PrivateAttr,
|
|
42
|
+
ValidationError,
|
|
42
43
|
ValidationInfo,
|
|
43
44
|
field_serializer,
|
|
44
45
|
field_validator,
|
|
45
46
|
model_validator,
|
|
46
47
|
)
|
|
48
|
+
from pydantic_core import InitErrorDetails
|
|
47
49
|
|
|
48
50
|
from .db.dialects import get_supported_dialects
|
|
49
51
|
from .db.sqltypes import get_type_func
|
|
@@ -758,7 +760,10 @@ class ColumnGroup(BaseObject):
|
|
|
758
760
|
for col in self.columns:
|
|
759
761
|
if isinstance(col, str):
|
|
760
762
|
# Dereference ColumnRef to Column object
|
|
761
|
-
|
|
763
|
+
try:
|
|
764
|
+
col_obj = self.table._find_column_by_id(col)
|
|
765
|
+
except KeyError as e:
|
|
766
|
+
raise ValueError(f"Column '{col}' not found in table '{self.table.name}'") from e
|
|
762
767
|
dereferenced_columns.append(col_obj)
|
|
763
768
|
else:
|
|
764
769
|
dereferenced_columns.append(col)
|
|
@@ -908,7 +913,7 @@ class Table(BaseObject):
|
|
|
908
913
|
for column in self.columns:
|
|
909
914
|
if column.id == id:
|
|
910
915
|
return column
|
|
911
|
-
raise
|
|
916
|
+
raise KeyError(f"Column '{id}' not found in table '{self.name}'")
|
|
912
917
|
|
|
913
918
|
@model_validator(mode="after")
|
|
914
919
|
def dereference_column_groups(self: Table) -> Table:
|
|
@@ -1048,6 +1053,36 @@ def _strip_ids(data: Any) -> Any:
|
|
|
1048
1053
|
return data
|
|
1049
1054
|
|
|
1050
1055
|
|
|
1056
|
+
def _append_error(
|
|
1057
|
+
errors: list[InitErrorDetails],
|
|
1058
|
+
loc: tuple,
|
|
1059
|
+
input_value: Any,
|
|
1060
|
+
error_message: str,
|
|
1061
|
+
error_type: str = "value_error",
|
|
1062
|
+
) -> None:
|
|
1063
|
+
"""Append an error to the errors list.
|
|
1064
|
+
|
|
1065
|
+
Parameters
|
|
1066
|
+
----------
|
|
1067
|
+
errors : list[InitErrorDetails]
|
|
1068
|
+
The list of errors to append to.
|
|
1069
|
+
loc : tuple
|
|
1070
|
+
The location of the error in the schema.
|
|
1071
|
+
input_value : Any
|
|
1072
|
+
The input value that caused the error.
|
|
1073
|
+
error_message : str
|
|
1074
|
+
The error message to include in the context.
|
|
1075
|
+
"""
|
|
1076
|
+
errors.append(
|
|
1077
|
+
{
|
|
1078
|
+
"type": error_type,
|
|
1079
|
+
"loc": loc,
|
|
1080
|
+
"input": input_value,
|
|
1081
|
+
"ctx": {"error": error_message},
|
|
1082
|
+
}
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
|
|
1051
1086
|
class Schema(BaseObject, Generic[T]):
|
|
1052
1087
|
"""Database schema model.
|
|
1053
1088
|
|
|
@@ -1230,18 +1265,19 @@ class Schema(BaseObject, Generic[T]):
|
|
|
1230
1265
|
|
|
1231
1266
|
return self
|
|
1232
1267
|
|
|
1233
|
-
|
|
1268
|
+
@model_validator(mode="after")
|
|
1269
|
+
def create_id_map(self: Schema) -> Schema:
|
|
1234
1270
|
"""Create a map of IDs to objects.
|
|
1235
1271
|
|
|
1272
|
+
Returns
|
|
1273
|
+
-------
|
|
1274
|
+
`Schema`
|
|
1275
|
+
The schema with the ID map created.
|
|
1276
|
+
|
|
1236
1277
|
Raises
|
|
1237
1278
|
------
|
|
1238
1279
|
ValueError
|
|
1239
1280
|
Raised if duplicate identifiers are found in the schema.
|
|
1240
|
-
|
|
1241
|
-
Notes
|
|
1242
|
-
-----
|
|
1243
|
-
This is called automatically by the `model_post_init` method. If the
|
|
1244
|
-
ID map is already populated, this method will return immediately.
|
|
1245
1281
|
"""
|
|
1246
1282
|
if self._id_map:
|
|
1247
1283
|
logger.debug("Ignoring call to create_id_map() - ID map was already populated")
|
|
@@ -1252,25 +1288,152 @@ class Schema(BaseObject, Generic[T]):
|
|
|
1252
1288
|
raise ValueError(
|
|
1253
1289
|
"Duplicate IDs found in schema:\n " + "\n ".join(visitor.duplicates) + "\n"
|
|
1254
1290
|
)
|
|
1291
|
+
logger.debug("Created ID map with %d entries", len(self._id_map))
|
|
1255
1292
|
return self
|
|
1256
1293
|
|
|
1257
|
-
def
|
|
1258
|
-
|
|
1294
|
+
def _validate_column_id(
|
|
1295
|
+
self: Schema,
|
|
1296
|
+
column_id: str,
|
|
1297
|
+
loc: tuple,
|
|
1298
|
+
errors: list[InitErrorDetails],
|
|
1299
|
+
) -> None:
|
|
1300
|
+
"""Validate a column ID from a constraint and append errors if invalid.
|
|
1259
1301
|
|
|
1260
1302
|
Parameters
|
|
1261
1303
|
----------
|
|
1262
|
-
|
|
1263
|
-
The
|
|
1304
|
+
schema : Schema
|
|
1305
|
+
The schema being validated.
|
|
1306
|
+
column_id : str
|
|
1307
|
+
The column ID to validate.
|
|
1308
|
+
loc : tuple
|
|
1309
|
+
The location of the error in the schema.
|
|
1310
|
+
errors : list[InitErrorDetails]
|
|
1311
|
+
The list of errors to append to.
|
|
1312
|
+
"""
|
|
1313
|
+
if column_id not in self:
|
|
1314
|
+
_append_error(
|
|
1315
|
+
errors,
|
|
1316
|
+
loc,
|
|
1317
|
+
column_id,
|
|
1318
|
+
f"Column ID '{column_id}' not found in schema",
|
|
1319
|
+
)
|
|
1320
|
+
elif not isinstance(self[column_id], Column):
|
|
1321
|
+
_append_error(
|
|
1322
|
+
errors,
|
|
1323
|
+
loc,
|
|
1324
|
+
column_id,
|
|
1325
|
+
f"ID '{column_id}' does not refer to a Column object",
|
|
1326
|
+
)
|
|
1264
1327
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1328
|
+
def _validate_foreign_key_column(
|
|
1329
|
+
self: Schema,
|
|
1330
|
+
column_id: str,
|
|
1331
|
+
table: Table,
|
|
1332
|
+
loc: tuple,
|
|
1333
|
+
errors: list[InitErrorDetails],
|
|
1334
|
+
) -> None:
|
|
1335
|
+
"""Validate a foreign key column ID from a constraint and append errors
|
|
1336
|
+
if invalid.
|
|
1337
|
+
|
|
1338
|
+
Parameters
|
|
1339
|
+
----------
|
|
1340
|
+
schema : Schema
|
|
1341
|
+
The schema being validated.
|
|
1342
|
+
column_id : str
|
|
1343
|
+
The foreign key column ID to validate.
|
|
1344
|
+
loc : tuple
|
|
1345
|
+
The location of the error in the schema.
|
|
1346
|
+
errors : list[InitErrorDetails]
|
|
1347
|
+
The list of errors to append to.
|
|
1348
|
+
"""
|
|
1349
|
+
try:
|
|
1350
|
+
table._find_column_by_id(column_id)
|
|
1351
|
+
except KeyError:
|
|
1352
|
+
_append_error(
|
|
1353
|
+
errors,
|
|
1354
|
+
loc,
|
|
1355
|
+
column_id,
|
|
1356
|
+
f"Column '{column_id}' not found in table '{table.name}'",
|
|
1357
|
+
)
|
|
1358
|
+
|
|
1359
|
+
@model_validator(mode="after")
|
|
1360
|
+
def check_constraints(self: Schema) -> Schema:
|
|
1361
|
+
"""Check constraint objects for validity. This needs to be deferred
|
|
1362
|
+
until after the schema is fully loaded and the ID map is created.
|
|
1363
|
+
|
|
1364
|
+
Raises
|
|
1365
|
+
------
|
|
1366
|
+
pydantic.ValidationError
|
|
1367
|
+
Raised if any constraints are invalid.
|
|
1269
1368
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1369
|
+
Returns
|
|
1370
|
+
-------
|
|
1371
|
+
`Schema`
|
|
1372
|
+
The schema being validated.
|
|
1272
1373
|
"""
|
|
1273
|
-
|
|
1374
|
+
errors: list[InitErrorDetails] = []
|
|
1375
|
+
|
|
1376
|
+
for table_index, table in enumerate(self.tables):
|
|
1377
|
+
for constraint_index, constraint in enumerate(table.constraints):
|
|
1378
|
+
column_ids: list[str] = []
|
|
1379
|
+
referenced_column_ids: list[str] = []
|
|
1380
|
+
|
|
1381
|
+
if isinstance(constraint, ForeignKeyConstraint):
|
|
1382
|
+
column_ids += constraint.columns
|
|
1383
|
+
referenced_column_ids += constraint.referenced_columns
|
|
1384
|
+
elif isinstance(constraint, UniqueConstraint):
|
|
1385
|
+
column_ids += constraint.columns
|
|
1386
|
+
# No extra checks are required on CheckConstraint objects.
|
|
1387
|
+
|
|
1388
|
+
# Validate the foreign key columns
|
|
1389
|
+
for column_id in column_ids:
|
|
1390
|
+
self._validate_column_id(
|
|
1391
|
+
column_id,
|
|
1392
|
+
(
|
|
1393
|
+
"tables",
|
|
1394
|
+
table_index,
|
|
1395
|
+
"constraints",
|
|
1396
|
+
constraint_index,
|
|
1397
|
+
"columns",
|
|
1398
|
+
column_id,
|
|
1399
|
+
),
|
|
1400
|
+
errors,
|
|
1401
|
+
)
|
|
1402
|
+
# Check that the foreign key column is within the source
|
|
1403
|
+
# table.
|
|
1404
|
+
self._validate_foreign_key_column(
|
|
1405
|
+
column_id,
|
|
1406
|
+
table,
|
|
1407
|
+
(
|
|
1408
|
+
"tables",
|
|
1409
|
+
table_index,
|
|
1410
|
+
"constraints",
|
|
1411
|
+
constraint_index,
|
|
1412
|
+
"columns",
|
|
1413
|
+
column_id,
|
|
1414
|
+
),
|
|
1415
|
+
errors,
|
|
1416
|
+
)
|
|
1417
|
+
|
|
1418
|
+
# Validate the primary key (reference) columns
|
|
1419
|
+
for referenced_column_id in referenced_column_ids:
|
|
1420
|
+
self._validate_column_id(
|
|
1421
|
+
referenced_column_id,
|
|
1422
|
+
(
|
|
1423
|
+
"tables",
|
|
1424
|
+
table_index,
|
|
1425
|
+
"constraints",
|
|
1426
|
+
constraint_index,
|
|
1427
|
+
"referenced_columns",
|
|
1428
|
+
referenced_column_id,
|
|
1429
|
+
),
|
|
1430
|
+
errors,
|
|
1431
|
+
)
|
|
1432
|
+
|
|
1433
|
+
if errors:
|
|
1434
|
+
raise ValidationError.from_exception_data("Schema validation failed", errors)
|
|
1435
|
+
|
|
1436
|
+
return self
|
|
1274
1437
|
|
|
1275
1438
|
def __getitem__(self, id: str) -> BaseObject:
|
|
1276
1439
|
"""Get an object by its ID.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-felis
|
|
3
|
-
Version: 29.2025.
|
|
3
|
+
Version: 29.2025.2600
|
|
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+)
|
|
@@ -451,6 +451,105 @@ class ConstraintTestCase(unittest.TestCase):
|
|
|
451
451
|
with self.assertRaises(ValidationError):
|
|
452
452
|
UniqueConstraint(name="uniq_test", id="#uniq_test", columns=["test_column"], type="BAD_TYPE")
|
|
453
453
|
|
|
454
|
+
def test_constraint_column_checks(self) -> None:
|
|
455
|
+
"""Test the extra validation in the ``Schema`` that checks the
|
|
456
|
+
constraint column references.
|
|
457
|
+
"""
|
|
458
|
+
|
|
459
|
+
def _create_test_schema(constraint: Constraint) -> None:
|
|
460
|
+
"""Create a test schema with the given constraint."""
|
|
461
|
+
test_col = Column(name="testColumn", id="#test_col_id", datatype="int")
|
|
462
|
+
test_col2 = Column(name="testColumn2", id="#test_col_id2", datatype="int")
|
|
463
|
+
test_tbl = Table(
|
|
464
|
+
name="testTable", id="#test_tbl_id", columns=[test_col, test_col2], constraints=[constraint]
|
|
465
|
+
)
|
|
466
|
+
test_col = Column(name="testColumn", id="#test_col2_id", datatype="int")
|
|
467
|
+
test_col2 = Column(name="testColumn2", id="#test_col2_id2", datatype="int")
|
|
468
|
+
test_tbl2 = Table(name="testTable2", id="#test_tbl2_id", columns=[test_col, test_col2])
|
|
469
|
+
Schema(name="testSchema", id="#test_schema_id", tables=[test_tbl, test_tbl2])
|
|
470
|
+
|
|
471
|
+
# Creating a unique constraint on a bad column should raise an
|
|
472
|
+
# exception.
|
|
473
|
+
with self.assertRaises(ValidationError):
|
|
474
|
+
_create_test_schema(
|
|
475
|
+
UniqueConstraint(name="testConstraint", id="#test_constraint_id", columns=["bad_column"])
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
# Creating a foreign key constraint with a bad column should raise an
|
|
479
|
+
# exception.
|
|
480
|
+
with self.assertRaises(ValidationError):
|
|
481
|
+
_create_test_schema(
|
|
482
|
+
ForeignKeyConstraint(
|
|
483
|
+
name="testForeignKey",
|
|
484
|
+
id="#test_fk_id",
|
|
485
|
+
columns=["bad_column"],
|
|
486
|
+
referenced_columns=["#test_col2_id"],
|
|
487
|
+
)
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
# Creating a foreign key constraint with a bad referenced column should
|
|
491
|
+
# raise an exception.
|
|
492
|
+
with self.assertRaises(ValidationError):
|
|
493
|
+
_create_test_schema(
|
|
494
|
+
ForeignKeyConstraint(
|
|
495
|
+
name="testForeignKey",
|
|
496
|
+
id="#test_fk_id",
|
|
497
|
+
columns=["#test_col_id"],
|
|
498
|
+
referenced_columns=["bad_column"],
|
|
499
|
+
)
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
# Creating a foreign key constraint where the source column is not in
|
|
503
|
+
# the same table as the constraint should raise an exception.
|
|
504
|
+
with self.assertRaises(ValidationError):
|
|
505
|
+
_create_test_schema(
|
|
506
|
+
ForeignKeyConstraint(
|
|
507
|
+
name="testForeignKey",
|
|
508
|
+
id="#test_fk_id",
|
|
509
|
+
columns=["#test_col2_id"], # This column is in test_tbl2, not test_tbl
|
|
510
|
+
referenced_columns=["#test_col_id"],
|
|
511
|
+
)
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
# Creating a foreign key constraint where the referenced column is not
|
|
515
|
+
# a column object should raise an exception.
|
|
516
|
+
with self.assertRaises(ValidationError):
|
|
517
|
+
_create_test_schema(
|
|
518
|
+
ForeignKeyConstraint(
|
|
519
|
+
name="testForeignKey",
|
|
520
|
+
id="#test_fk_id",
|
|
521
|
+
columns=["#test_col_id"],
|
|
522
|
+
referenced_columns=["#test_schema_id"],
|
|
523
|
+
)
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
# Creating a valid unique constraint should not raise an exception.
|
|
527
|
+
_create_test_schema(
|
|
528
|
+
UniqueConstraint(name="testConstraint", id="#test_constraint_id", columns=["#test_col_id"])
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
# Creating a valid foreign key constraint should not raise an
|
|
532
|
+
# exception.
|
|
533
|
+
_create_test_schema(
|
|
534
|
+
ForeignKeyConstraint(
|
|
535
|
+
name="testForeignKey",
|
|
536
|
+
id="#test_fk_id",
|
|
537
|
+
columns=["#test_col_id"],
|
|
538
|
+
referenced_columns=["#test_col2_id"],
|
|
539
|
+
)
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
# Creating a foreign key constraint with a composite key should not
|
|
543
|
+
# raise an exception.
|
|
544
|
+
_create_test_schema(
|
|
545
|
+
ForeignKeyConstraint(
|
|
546
|
+
name="testCompositeForeignKey",
|
|
547
|
+
id="#test_composite_fk_id",
|
|
548
|
+
columns=["#test_col_id", "#test_col_id2"],
|
|
549
|
+
referenced_columns=["#test_col2_id", "#test_col2_id2"],
|
|
550
|
+
)
|
|
551
|
+
)
|
|
552
|
+
|
|
454
553
|
|
|
455
554
|
class IndexTestCase(unittest.TestCase):
|
|
456
555
|
"""Test Pydantic validation of the ``Index`` class."""
|
|
@@ -575,8 +674,8 @@ class SchemaTestCase(unittest.TestCase):
|
|
|
575
674
|
|
|
576
675
|
def test_check_unique_index_names(self) -> None:
|
|
577
676
|
"""Test that index names are unique."""
|
|
578
|
-
test_col = Column(name="test_column1", id="#test_table
|
|
579
|
-
test_col2 = Column(name="test_column2", id="
|
|
677
|
+
test_col = Column(name="test_column1", id="#test_table.test_column1", datatype="int")
|
|
678
|
+
test_col2 = Column(name="test_column2", id="#test_table.test_column2", datatype="string", length=256)
|
|
580
679
|
test_tbl = Table(name="test_table", id="#test_table", columns=[test_col, test_col2])
|
|
581
680
|
test_idx = Index(name="idx_test", id="#idx_test", columns=[test_col.id])
|
|
582
681
|
test_idx2 = Index(name="idx_test", id="#idx_test2", columns=[test_col2.id])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/columns.csv
RENAMED
|
File without changes
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/key_columns.csv
RENAMED
|
File without changes
|
|
File without changes
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/schemas.csv
RENAMED
|
File without changes
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/felis/config/tap_schema/tables.csv
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
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{lsst_felis-29.2025.2500 → lsst_felis-29.2025.2600}/python/lsst_felis.egg-info/top_level.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
|
|
File without changes
|