У меня есть две таблицы в моей базе данных
план и план_руль. План содержит несколько правил
Я создал свою таблицу plan_rule следующим образом, поэтому она имеет каскадное удаление для записей, у которых в строке нет plan_id
CREATE TABLE [dbo].[plan_rule](
[created_by] [VARCHAR](25) NULL,
[created_datetime] [DATETIME] NULL,
[modified_by] [VARCHAR](25) NULL,
[modified_datetime] [DATETIME] NULL,
[active] [BIT] NULL,
[id] [INT] IDENTITY(1,1) NOT NULL,
[plan_id] [INT] NOT NULL,
[rule_data] [INT] NOT NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[plan_rule] WITH CHECK ADD CONSTRAINT [CK_plan_rule_Cascade] FOREIGN KEY([plan_id])
REFERENCES [dbo].[plan] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[plan_rule] CHECK CONSTRAINT [CK_plan_rule_Cascade]
GO
В питоне я определил мои отношения следующим образом
class Plan(Base):
__tablename__ = 'plan'
id = Column(Integer, Sequence('plan_id_seq'), primary_key=True)
plan_name = Column(Unicode(255), nullable=False)
plan_rules = relationship(
"PlanRule",
# uselist=False,
backref="plan"
)
def __init__(self, request=None, params=None):
self.initialize(request=request, params=params)
Когда я обновляю план и его правила, у меня есть только идентификатор плана, поэтому я удаляю все мои plan_rules и заново добавляю все (существует очень небольшое подмножество правил, поэтому проще просто удалить все правила и повторно их добавить).
Я пытаюсь сделать это следующим образом
def save_rules(request, params, rec_id, plan):
rules = find_rule_params(params, plan.id)
if rec_id: #there is an update to the plan
plan.plan_rules = [] #clear old rules
for rule in rules:
try:
rec = PlanRule(request=request, params=rule)
except Exception as e:
# If there are errors adding, abort
LOG.exception('Encountered error during plan creation:')
transaction.abort()
resp = {
'status': False,
'message': 'Unable to add a record due to database constraints.'
}
return resp
# If there are errors adding, abort
if rec.errors:
transaction.abort()
resp = {'status': False, 'errors': rec.errors}
LOG.debug('Encountered errors while adding a plan: {}'.format(resp))
return resp
# Success! Set modification fields
rec.modified_by = rec.created_by = request.remote_user
# Load relationships before dictifying
rec.load_relationships()
plan.plan_rules.append(rec) #add the new record
return plan
Следующий код хорошо работает для новых правил, но когда я пытаюсь выполнить обновление, я получаю следующую ошибку
Обнаружена ошибка при создании плана:
Traceback (most recent call last):
rec = PlanRule(request=request, params=rule)
IntegrityError: (pymssql.IntegrityError) (515, "Cannot insert the value NULL into column 'plan_id', table 'plan_rule'; column does not allow nulls. UPDATE fails.DB-Lib error message 20018, severity 16:\nGeneral SQL Server error: Check messages from the SQL Server\n") [SQL: 'UPDATE plan_rule SET plan_id=%(plan_id)s WHERE plan_rule.id = %(plan_rule_id)s'] [parameters: ({'plan_id': None, 'plan_rule_id': 1}, {'plan_id': None, 'plan_rule_id': 2}, {'plan_id': None, 'plan_rule_id': 3})] (Background on this error at: http://sqlalche.me/e/gkpj)
Я предполагаю, что это как-то связано с тем, как я удаляю старые строки из таблицы, но я не уверен, почему это не работает.