diff --git a/gns3server/db/models/llm_model_configs.py b/gns3server/db/models/llm_model_configs.py index 2656ed83a..a7e5fe8ad 100644 --- a/gns3server/db/models/llm_model_configs.py +++ b/gns3server/db/models/llm_model_configs.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from sqlalchemy import Column, Boolean, ForeignKey, CheckConstraint, UniqueConstraint, Index, Integer, String +from sqlalchemy import Column, Boolean, ForeignKey, CheckConstraint, Index, Integer, String, text from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.orm import relationship @@ -65,14 +65,12 @@ class LLMModelConfig(BaseTable): "model_type IN ('text', 'vision', 'stt', 'tts', 'multimodal', 'embedding', 'reranking', 'other')", name="valid_model_type_check" ), - # Each user can have at most one default config - UniqueConstraint("user_id", "is_default", name="unique_user_default", - deferrable=True, initially="deferred", - postgresql_where="is_default = TRUE AND user_id IS NOT NULL"), - # Each group can have at most one default config - UniqueConstraint("group_id", "is_default", name="unique_group_default", - deferrable=True, initially="deferred", - postgresql_where="is_default = TRUE AND group_id IS NOT NULL"), + # Each user can have at most one default config (partial unique index) + Index("unique_user_default", "user_id", unique=True, + postgresql_where=text("is_default = TRUE AND user_id IS NOT NULL")), + # Each group can have at most one default config (partial unique index) + Index("unique_group_default", "group_id", unique=True, + postgresql_where=text("is_default = TRUE AND group_id IS NOT NULL")), # Indexes for efficient queries Index("idx_llm_model_configs_user_id", "user_id"), Index("idx_llm_model_configs_group_id", "group_id"), diff --git a/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py b/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py index 007bde3b1..400c7482f 100644 --- a/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py +++ b/gns3server/db_migrations/versions/20260303_create_llm_model_configs_table.py @@ -54,18 +54,6 @@ def upgrade() -> None: "model_type IN ('text', 'vision', 'stt', 'tts', 'multimodal', 'embedding', 'reranking', 'other')", name='valid_model_type_check' ), - sa.UniqueConstraint( - 'user_id', 'is_default', - name='unique_user_default', - deferrable=True, initially='deferred', - postgresql_where=sa.text("is_default = TRUE AND user_id IS NOT NULL") - ), - sa.UniqueConstraint( - 'group_id', 'is_default', - name='unique_group_default', - deferrable=True, initially='deferred', - postgresql_where=sa.text("is_default = TRUE AND group_id IS NOT NULL") - ), ) # Create indexes for efficient queries @@ -74,6 +62,20 @@ def upgrade() -> None: op.create_index('idx_llm_model_configs_model_type', 'llm_model_configs', ['model_type']) op.create_index('idx_llm_model_configs_config', 'llm_model_configs', ['config'], postgresql_using='gin') + # Create partial unique indexes for default configs + # Each user can have at most one default config + op.execute(""" + CREATE UNIQUE INDEX unique_user_default + ON llm_model_configs (user_id) + WHERE is_default = TRUE AND user_id IS NOT NULL + """) + # Each group can have at most one default config + op.execute(""" + CREATE UNIQUE INDEX unique_group_default + ON llm_model_configs (group_id) + WHERE is_default = TRUE AND group_id IS NOT NULL + """) + def downgrade() -> None: # Drop indexes @@ -81,6 +83,8 @@ def downgrade() -> None: op.drop_index('idx_llm_model_configs_model_type', table_name='llm_model_configs') op.drop_index('idx_llm_model_configs_group_id', table_name='llm_model_configs') op.drop_index('idx_llm_model_configs_user_id', table_name='llm_model_configs') + op.drop_index('unique_user_default', table_name='llm_model_configs') + op.drop_index('unique_group_default', table_name='llm_model_configs') # Drop table op.drop_table('llm_model_configs') diff --git a/gns3server/schemas/__init__.py b/gns3server/schemas/__init__.py index d04218f9b..9d1d54058 100644 --- a/gns3server/schemas/__init__.py +++ b/gns3server/schemas/__init__.py @@ -35,7 +35,6 @@ from .controller.llm_model_configs import ( LLMModelConfigCreate, LLMModelConfigUpdate, LLMModelConfigResponse, - LLMModelConfigListResponse, LLMModelConfigWithSource, LLMModelConfigInheritedResponse )