Skip to content

Commit 5bd2ef0

Browse files
committed
feat(model): res position unique index;
- Create a unique index for active resource positions.
1 parent 67c562b commit 5bd2ef0

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""empty message
2+
3+
Revision ID: e12e991f586b
4+
Revises: f7b64c701a10
5+
Create Date: 2026-02-10 18:26:31.122945
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'e12e991f586b'
14+
down_revision = 'f7b64c701a10'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
op.create_index(
21+
"idx_package_resource_unique_position", "resource",
22+
[sa.Column('package_id'), sa.Column('position')],
23+
unique=True, postgresql_where=sa.text('"resource".state=\'active\''))
24+
print('Created "idx_package_resource_unique_position" index')
25+
26+
27+
def downgrade():
28+
op.drop_index("idx_package_resource_unique_position")
29+
print('Dropped "idx_package_resource_unique_position" index')

ckan/model/resource.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
Index('idx_package_resource_id', 'id'),
6060
Index('idx_package_resource_package_id', 'package_id'),
6161
Index('idx_package_resource_url', 'url'),
62+
Index('idx_package_resource_unique_position',
63+
Column('package_id'), Column('position'),
64+
unique=True, postgresql_where="(state = 'active'::text)")
6265
)
6366

6467

ckan/tests/model/test_resource.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# encoding: utf-8
22

33
import pytest
4+
from sqlalchemy.exc import IntegrityError
45

56
import ckan.model as model
67
import ckan.tests.factories as factories
@@ -60,3 +61,20 @@ def test_package_purge_deletes_resources(self):
6061
model.repo.commit_and_remove()
6162

6263
assert model.Resource.active().count() == initial
64+
65+
def test_resource_unique_positions(self):
66+
"""
67+
Position values should be unique per dataset.
68+
"""
69+
parent = factories.Dataset()
70+
factories.Resource(package_id=parent["id"])
71+
res2 = factories.Resource(package_id=parent["id"])
72+
73+
res2.position = 0
74+
75+
with pytest.raises(IntegrityError) as e:
76+
model.Session.add(res2)
77+
model.Session.commit()
78+
79+
err = e.value
80+
assert 'duplicate key value violates unique constraint "idx_package_resource_unique_position"' in str(err)

0 commit comments

Comments
 (0)