diff --git a/alembic/versions/ffba7564d918_initialise_base_database_structure.py b/alembic/versions/1a69295f277f_initialise_base_database_structure.py similarity index 98% rename from alembic/versions/ffba7564d918_initialise_base_database_structure.py rename to alembic/versions/1a69295f277f_initialise_base_database_structure.py index 88327fb..e571ef8 100644 --- a/alembic/versions/ffba7564d918_initialise_base_database_structure.py +++ b/alembic/versions/1a69295f277f_initialise_base_database_structure.py @@ -1,8 +1,8 @@ """initialise base database structure -Revision ID: ffba7564d918 +Revision ID: 1a69295f277f Revises: -Create Date: 2024-03-07 23:24:44.015377 +Create Date: 2024-03-16 12:46:26.532739 """ from typing import Sequence, Union @@ -12,7 +12,7 @@ from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. -revision: str = 'ffba7564d918' +revision: str = '1a69295f277f' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -42,7 +42,7 @@ def upgrade() -> None: sa.Column('extensions', postgresql.JSONB(astext_type=sa.Text()), nullable=True, comment='If defined, 1 or more data model extensions associated with the ProductFootprint.'), sa.PrimaryKeyConstraint('pk') ) - op.create_index(op.f('ix_productfootprint_id'), 'productfootprint', ['id'], unique=False) + op.create_index(op.f('ix_productfootprint_id'), 'productfootprint', ['id'], unique=True) op.create_table('user', sa.Column('id', sa.Integer(), nullable=False), sa.Column('username', sa.String(), nullable=False), diff --git a/db/models/product_footprint.py b/db/models/product_footprint.py index bf1395f..8878220 100644 --- a/db/models/product_footprint.py +++ b/db/models/product_footprint.py @@ -8,7 +8,7 @@ class ProductFootprint(Base): pk = Column(Integer, primary_key=True, autoincrement=True) - id = Column(String, index=True, comment="The product footprint identifier.") + id = Column(String, index=True, unique=True, comment="The product footprint identifier.") # need some smarts around this precedingPfIds = Column(ARRAY(String), comment="non-empty set of preceding product footprint identifiers without duplicates.") specVersion = Column(String, comment="The version of the ProductFootprint data specification.") diff --git a/tests/test_models/test_product_footprint_model.py b/tests/test_models/test_product_footprint_model.py index 768130b..5c5e5e3 100644 --- a/tests/test_models/test_product_footprint_model.py +++ b/tests/test_models/test_product_footprint_model.py @@ -1,5 +1,8 @@ from datetime import datetime, timezone +import pytest +from sqlalchemy.exc import IntegrityError + from db.models.product_footprint import ProductFootprint, ProductFootprintStatus from db.models.carbon_footprint import CarbonFootprintModel, ProductOrSectorSpecificRuleModel, EmissionFactorDatasetModel from schemas.carbon_footprint import ( @@ -101,3 +104,22 @@ def test_product_footprint_creation(db_session): def test_product_footprint_status_values(): assert ProductFootprintStatus.ACTIVE.value == "Active" assert ProductFootprintStatus.DEPRECATED.value == "Deprecated" + + +def test_product_footprint_id_field_is_unique(db_session): + # Create a record + record1 = ProductFootprint( + id="test_for_uniqueness", + comment="test" + ) + db_session.add(record1) + db_session.commit() + + # Attempt to create another record with the same id + record2 = ProductFootprint( + id="test_for_uniqueness", + comment = "test" + ) + db_session.add(record2) + with pytest.raises(IntegrityError, match="duplicate key value violates unique constraint"): + db_session.commit()