Added composite unique name constraints

In this changeset, I added composite contraints on models that
were currently subject to an implicit uniqueness.
This composite constraint takes as an input the name and the deleted
columns.
The 'deleted' column is 0 by default and is updated with the value of
the associated 'id' column upon soft deletion.
What this means is that this composite constraint guarantees the fact
that we can hold many soft deleted records holding the exact same name.
Indeed, the value of the deleted column will be different whilst
forbidding 2 non-soft deleted records with the same name as their
associated 'deleted' value will be 0 and subsequently violates the
constraint.

Change-Id: I3ee39e23aa4ca9bc6b4ea9af8c6b7e6d67af0136
This commit is contained in:
Vincent Françoise
2016-10-06 11:20:44 +02:00
parent 431b54fb4c
commit 10cbcd2432
2 changed files with 17 additions and 9 deletions

View File

@@ -27,10 +27,10 @@ from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import Numeric
from sqlalchemy import schema
from sqlalchemy import String
from sqlalchemy import Text
from sqlalchemy.types import TypeDecorator, TEXT
from sqlalchemy import UniqueConstraint
from watcher.common import paths
@@ -116,7 +116,8 @@ class Strategy(Base):
__tablename__ = 'strategies'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_strategies0uuid'),
UniqueConstraint('uuid', name='uniq_strategies0uuid'),
UniqueConstraint('name', 'deleted', name='uniq_strategies0name'),
table_args()
)
id = Column(Integer, primary_key=True)
@@ -132,7 +133,8 @@ class Goal(Base):
__tablename__ = 'goals'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_goals0uuid'),
UniqueConstraint('uuid', name='uniq_goals0uuid'),
UniqueConstraint('name', 'deleted', name='uniq_goals0name'),
table_args(),
)
id = Column(Integer, primary_key=True)
@@ -147,7 +149,8 @@ class AuditTemplate(Base):
__tablename__ = 'audit_templates'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_audit_templates0uuid'),
UniqueConstraint('uuid', name='uniq_audit_templates0uuid'),
UniqueConstraint('name', 'deleted', name='uniq_audit_templates0name'),
table_args()
)
id = Column(Integer, primary_key=True)
@@ -166,7 +169,7 @@ class Audit(Base):
__tablename__ = 'audits'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_audits0uuid'),
UniqueConstraint('uuid', name='uniq_audits0uuid'),
table_args()
)
id = Column(Integer, primary_key=True)
@@ -186,7 +189,7 @@ class Action(Base):
__tablename__ = 'actions'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_actions0uuid'),
UniqueConstraint('uuid', name='uniq_actions0uuid'),
table_args()
)
id = Column(Integer, primary_key=True)
@@ -205,7 +208,7 @@ class ActionPlan(Base):
__tablename__ = 'action_plans'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_action_plans0uuid'),
UniqueConstraint('uuid', name='uniq_action_plans0uuid'),
table_args()
)
id = Column(Integer, primary_key=True)
@@ -222,7 +225,7 @@ class EfficacyIndicator(Base):
__tablename__ = 'efficacy_indicators'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_efficacy_indicators0uuid'),
UniqueConstraint('uuid', name='uniq_efficacy_indicators0uuid'),
table_args()
)
id = Column(Integer, primary_key=True)
@@ -240,7 +243,8 @@ class ScoringEngine(Base):
__tablename__ = 'scoring_engines'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_scoring_engines0uuid'),
UniqueConstraint('uuid', name='uniq_scoring_engines0uuid'),
UniqueConstraint('name', 'deleted', name='uniq_scoring_engines0name'),
table_args()
)
id = Column(Integer, primary_key=True)

View File

@@ -145,11 +145,13 @@ class TestListStrategy(api_base.FunctionalTest):
obj_utils.create_test_strategy(
self.context, id=id_,
uuid=utils.generate_uuid(),
name='Goal %s' % id_,
goal_id=goal1['id'])
for id_ in range(3, 5):
obj_utils.create_test_strategy(
self.context, id=id_,
uuid=utils.generate_uuid(),
name='Goal %s' % id_,
goal_id=goal2['id'])
response = self.get_json('/strategies/?goal=%s' % goal1['uuid'])
@@ -175,11 +177,13 @@ class TestListStrategy(api_base.FunctionalTest):
obj_utils.create_test_strategy(
self.context, id=id_,
uuid=utils.generate_uuid(),
name='Goal %s' % id_,
goal_id=goal1['id'])
for id_ in range(3, 5):
obj_utils.create_test_strategy(
self.context, id=id_,
uuid=utils.generate_uuid(),
name='Goal %s' % id_,
goal_id=goal2['id'])
response = self.get_json('/strategies/?goal=%s' % goal1['name'])