diff --git a/mitm_tooling/definition/definition_representation.py b/mitm_tooling/definition/definition_representation.py index 523a4fc7d609cf86a1dfab0324c04c6ccc321303..f34b23f15ffba8908bc56a30a32c5e90c6ddf635 100644 --- a/mitm_tooling/definition/definition_representation.py +++ b/mitm_tooling/definition/definition_representation.py @@ -64,6 +64,7 @@ class ConceptProperties(pydantic.BaseModel): props = dict(self.__dict__) del props['nature'] del props['key'] + del props['plural'] return props @property diff --git a/mitm_tooling/definition/maed.yaml b/mitm_tooling/definition/maed.yaml index b43933a2b0f7f781f178635af2ee8a441202928e..114cc154c3385c6af7f7c0b6b8f2784e280a4ba6 100644 --- a/mitm_tooling/definition/maed.yaml +++ b/mitm_tooling/definition/maed.yaml @@ -54,7 +54,7 @@ owned-relations: concept: concept segment_index: index foreign: - fk: + associated-segment: segment: object: object concept: concept diff --git a/mitm_tooling/representation/sql_representation.py b/mitm_tooling/representation/sql_representation.py index 195cc19bcd59f46f8efd19fe8d78f1540597d5f2..462b9a30d953257b308ad70ed6628b006cc7f760 100644 --- a/mitm_tooling/representation/sql_representation.py +++ b/mitm_tooling/representation/sql_representation.py @@ -15,8 +15,8 @@ from sqlalchemy_utils.view import create_view from mitm_tooling.definition import RelationName from mitm_tooling.definition.definition_tools import ColGroupMaps from mitm_tooling.utilities.sql_utils import create_sa_engine, qualify -from . import Header, MITMData from .common import * +from .intermediate_representation import Header, MITMData from .sql.common import * from ..utilities.io_utils import FilePath @@ -31,7 +31,8 @@ ConceptTablesDict = dict[ConceptName, sa.Table] ConceptTypeTablesDict = dict[ConceptName, dict[str, sa.Table]] MitMConceptSchemaItemGenerator = Callable[ - [MITM, ConceptName, ColumnsDict, ColumnsDict | None], Generator[sqlalchemy.sql.schema.SchemaItem, None, None]] + [MITM, ConceptName, TableName, ColumnsDict, ColumnsDict | None], Generator[ + sqlalchemy.sql.schema.SchemaItem, None, None]] MitMConceptColumnGenerator = Callable[ [MITM, ConceptName], Generator[tuple[str, sa.Column], None, None]] MitMDBViewsGenerator = Callable[[MITM, ConceptTablesDict, ConceptTypeTablesDict], @@ -84,7 +85,9 @@ def pick_table_pk(mitm: MITM, concept: ConceptName, created_columns: ColumnsDict mitm_def = get_mitm_def(mitm) concept_properties, concept_relations = mitm_def.get(concept) - prepended_cols = lambda: [_within_concept_id_col(mitm, concept)] if not has_natural_pk(mitm, concept) else None + prepended_cols = None + if not has_natural_pk(mitm, concept): + prepended_cols = lambda: [_within_concept_id_col(mitm, concept)] names, mapped_names = map_col_groups(mitm_def, concept, { 'kind': lambda: 'kind', 'type': lambda: concept_properties.typing_concept, @@ -94,32 +97,34 @@ def pick_table_pk(mitm: MITM, concept: ConceptName, created_columns: ColumnsDict return {n: created_columns[n] for n in names} -def _gen_pk_constraint(mitm: MITM, concept: ConceptName, created_columns: ColumnsDict, - pk_columns: ColumnsDict | None) -> Generator[ +def _gen_unique_constraint(mitm: MITM, concept: ConceptName, table_name: TableName, created_columns: ColumnsDict, + pk_columns: ColumnsDict | None) -> Generator[ sa.sql.schema.SchemaItem, None, None]: - yield sa.PrimaryKeyConstraint(*pk_columns.values()) + yield sa.UniqueConstraint(*pk_columns.values()) -def _gen_unique_constraint(mitm: MITM, concept: ConceptName, created_columns: ColumnsDict, - pk_columns: ColumnsDict | None) -> Generator[ +def _gen_pk_constraint(mitm: MITM, concept: ConceptName, table_name: TableName, created_columns: ColumnsDict, + pk_columns: ColumnsDict | None) -> Generator[ sa.sql.schema.SchemaItem, None, None]: - yield sa.UniqueConstraint(*pk_columns.values()) + yield sa.PrimaryKeyConstraint(*pk_columns.values()) -def _gen_index(mitm: MITM, concept: ConceptName, created_columns: ColumnsDict, +def _gen_index(mitm: MITM, concept: ConceptName, table_name: TableName, created_columns: ColumnsDict, pk_columns: ColumnsDict | None) -> Generator[ sa.sql.schema.SchemaItem, None, None]: - yield sa.Index(*pk_columns.values()) + yield sa.Index(f'{table_name}.index', *pk_columns.values(), unique=True) -def _gen_foreign_key_constraints(mitm: MITM, concept: ConceptName, created_columns: ColumnsDict, +def _gen_foreign_key_constraints(mitm: MITM, concept: ConceptName, table_name: TableName, created_columns: ColumnsDict, pk_columns: ColumnsDict | None) -> Generator[ sa.sql.schema.SchemaItem, None, None]: - _, concept_relations = get_mitm_def(mitm).get(concept) + mitm_def = get_mitm_def(mitm) + _, concept_relations = mitm_def.get(concept) # self_fk if pk_columns: - parent_table = mk_concept_table_name(mitm, concept) + parent_concept = mitm_def.get_parent(concept) + parent_table = mk_concept_table_name(mitm, parent_concept) cols, refcols = zip( *((c, qualify(table=parent_table, column=s)) for s, c in pk_columns.items())) yield sa.ForeignKeyConstraint(name='parent', columns=cols, refcolumns=refcols) @@ -148,7 +153,7 @@ def mk_table(meta: sa.MetaData, mitm: MITM, concept: ConceptName, table_name: Ta additional_column_generators: Iterable[MitMConceptColumnGenerator] | None = ( _gen_within_concept_id_col,), schema_item_generators: Iterable[MitMConceptSchemaItemGenerator] | - None = None, + None = (_gen_unique_constraint, _gen_pk_constraint, _gen_index,), override_schema: SchemaName | None = None) -> \ tuple[ sa.Table, ColumnsDict, ColumnsDict]: @@ -166,7 +171,7 @@ def mk_table(meta: sa.MetaData, mitm: MITM, concept: ConceptName, table_name: Ta schema_items: list[sa.sql.schema.SchemaItem] = [] if schema_item_generators is not None: for generator in schema_item_generators: - schema_items.extend(generator(mitm, concept, created_columns, pk_cols)) + schema_items.extend(generator(mitm, concept, table_name, created_columns, pk_cols)) return sa.Table(table_name, meta, schema=override_schema if override_schema else SQL_REPRESENTATION_DEFAULT_SCHEMA, *columns, @@ -186,23 +191,23 @@ def _gen_denormalized_views(mitm: MITM, concept_tables: ConceptTablesDict, type_ for concept in mitm_def.main_concepts: view_name = mk_concept_table_name(mitm, concept) + '_view' q = None - if concept_t := concept_tables.get(concept): + if (concept_t := concept_tables.get(concept)) is not None: if has_type_tables(mitm, concept): shared_cols = {c.name for c in concept_t.columns} if concept_type_tables := type_tables.get(concept): selections = [] for type_name, type_t in concept_type_tables.items(): - selection = (c if c.name in shared_cols else sa.alias(c, _prefix_col_name(type_name, c.name)) + selection = (c if c.name in shared_cols else sa.label(_prefix_col_name(type_name, c.name), c) for c in type_t.columns) - selections.append(sa.select(selection)) + selections.append(sa.select(*selection)) q = sa.union(*selections).subquery() else: q = sa.select(concept_t) - if q: + if q is not None: yield view_name, q for parent_concept, subs in mitm_def.sub_concept_map.items(): - if concept_t := concept_tables.get(parent_concept): + if (concept_t := concept_tables.get(parent_concept)) is not None: for sub in subs: view_name = mk_concept_table_name(mitm, sub) + '_view' k = mitm_def.get_properties(sub).key @@ -214,7 +219,7 @@ _view_generators: tuple[MitMDBViewsGenerator, ...] = (_gen_denormalized_views,) def mk_sql_rep_schema(header: Header, - view_generators: Iterable[MitMDBViewsGenerator] | None = None, + view_generators: Iterable[MitMDBViewsGenerator] | None = (_gen_denormalized_views,), override_schema: SchemaName | None = None) -> SQLRepresentationSchema: mitm_def = get_mitm_def(header.mitm) meta = sa.MetaData(schema=override_schema if override_schema else SQL_REPRESENTATION_DEFAULT_SCHEMA) @@ -269,8 +274,8 @@ def mk_sql_rep_schema(header: Header, zip(he.attributes, he.attribute_dtypes)], }, additional_column_generators=(_gen_within_concept_id_col,), schema_item_generators=( - _gen_unique_constraint, _gen_pk_constraint, - _gen_foreign_key_constraints, _gen_index), + _gen_unique_constraint, _gen_pk_constraint, _gen_index, + _gen_foreign_key_constraints), override_schema=override_schema) if he_concept not in type_tables: @@ -338,7 +343,8 @@ def insert_db_instances(bind: EngineOrConnection, sql_rep_schema: SQLRepresentat no_rows_to_insert = len(type_df) artificial_ids = pd.RangeIndex(start=max_id + 1, stop=max_id + 1 + no_rows_to_insert, name=concept_id_col_name) - type_df = type_df.assign(concept_id_col_name=artificial_ids) + type_df[concept_id_col_name] = artificial_ids + # type_df = type_df.assign({concept_id_col_name : artificial_ids}) conn.execute(t_concept.insert(), _df_to_table_records(type_df, t_concept))