Repository: OpenEnergyPlatform/oeplatform

Issue:
Multiple definitions of primary key error when defining PK on table column
See https://github.com/OpenEnergyPlatform/oedialect/issues/43 for reference

I will add a small PR to address this.


Discussion:
hi @henhuy. sorry to be late to the party. 

Unfortunately, the fix does not quite work. `if ccolumns in primary_key_col_names` is not ok, because both of the vars are lists.

I will create a new fix including a unittest

Resolving patch:
diff --git a/api/actions.py b/api/actions.py
--- a/api/actions.py
+++ b/api/actions.py
@@ -38,7 +38,6 @@
 from dataedit.structures import Tag as OEDBTag
 from oeplatform.securitysettings import PLAYGROUNDS, UNVERSIONED_SCHEMAS
 
-
 pgsql_qualifier = re.compile(r"^[\w\d_\.]+$")
 
 
@@ -108,9 +107,9 @@ def assert_permission(user, table, permission, schema=None):
 
 def assert_add_tag_permission(user, table, permission, schema):
     """
-    Tags can be added to tables that are in any schema. However, 
-    it is necessary to check whether the user has write permission 
-    to the table, since not every user should be able to add tags 
+    Tags can be added to tables that are in any schema. However,
+    it is necessary to check whether the user has write permission
+    to the table, since not every user should be able to add tags
     to every table.
 
     Args:
@@ -121,7 +120,7 @@ def assert_add_tag_permission(user, table, permission, schema):
 
     Raises:
         PermissionDenied: _description_
-    
+
     """
     # if not request.user.is_anonymous:
     #         level = request.user.get_table_permission_level(table)
@@ -866,7 +865,9 @@ def table_create(schema, table, column_definitions, constraints_definitions):
                 ccolumns = [constraint["constraint_parameter"]]
 
             if primary_key_col_names:
-                if ccolumns in primary_key_col_names:
+                # if table level PK constraint is set in addition
+                # to column level PK, both must be the same (#1110)
+                if set(ccolumns) == set(primary_key_col_names):
                     continue
                 raise APIError("Multiple definitions of primary key")
             primary_key_col_names = ccolumns
@@ -2295,7 +2296,7 @@ def set_table_metadata(table, schema, metadata, cursor=None):
     # update the table comment in oedb table if sqlalchemy curser is provided
     # ---------------------------------------
 
-    # TODO: The following 2 lines seems to duplicate with the lines below the if block 
+    # TODO: The following 2 lines seems to duplicate with the lines below the if block
     oedb_table_obj = _get_table(schema=schema, table=table)
     oedb_table_obj.comment = metadata_str
     if cursor is not None:


Test patch:
diff --git a/api/tests/test_regression/test_issue_739_enforce_id_pk.py b/api/tests/test_regression/test_issue_739_enforce_id_pk.py
--- a/api/tests/test_regression/test_issue_739_enforce_id_pk.py
+++ b/api/tests/test_regression/test_issue_739_enforce_id_pk.py
@@ -108,3 +108,18 @@ def test_err_on_multiple_pk(self):
             }
         )
         self.assertEqual(res.status_code, 400)
+
+    def test_ok_on_double_defined_pk(self):
+        """sqlalchemy sets column attribute primary_key=True
+        in addition to primary, which should work. (#1110)
+        """
+        res = self.create_table(
+            {
+                "columns": [
+                    {"name": "id", "data_type": "int", "primary_key": True},
+                    {"name": "value", "data_type": "int"},
+                ],
+                "constraints": [{"type": "primary_key", "columns": ["id"]}],
+            }
+        )
+        self.assertEqual(res.status_code, 201)