Я работаю с устаревшей БД в MSSQL. У нас есть таблица с двумя столбцами, которые вызывают у меня проблемы:
class Emp(models.Model):
empid = models.IntegerField(_("Unique ID"), unique=True, db_column=u'EMPID')
ssn = models.CharField(_("Social security number"), max_length=10, primary_key=True, db_column=u'SSN') # Field name made lowercase.
Таким образом, таблица имеет столбец ssn в качестве первичного ключа, и соответствующая часть кода обновления SQL, сгенерированного django, выглядит так:
UPDATE [EMP] SET [EMPID] = 399,
.........
WHERE [EMP].[SSN] = 2509882579
Проблема в том, что EMP.EMPID является полем идентификации в MSSQL, и поэтому pyodbc выдает эту ошибку всякий раз, когда я пытаюсь сохранить изменения в существующем сотруднике:
ProgrammingError: ('42000', "[42000] [Microsoft][SQL Native Client][SQL Server]C
annot update identity column 'EMPID'. (8102) (SQLExecDirectW); [42000] [Microsof
t][SQL Native Client][SQL Server]Statement(s) could not be prepared. (8180)")
Наличие EMP.EMPID в качестве идентификатора не имеет решающего значения для любой программы, поэтому удаление его путем создания временного столбца и копирования, удаления, переименования кажется логичной вещью. Это создает еще один шаг при переносе старых клиентов в Django, поэтому мой вопрос заключается в том, есть ли способ запретить Django генерировать фрагмент «[EMPID] = XXX» всякий раз, когда я обновляю эту таблицу? *
EDIT
Я исправил свою модель так:
def save(self, *args, **kwargs):
if self.empid:
self._meta.local_fields = [f for f in self._meta.local_fields if f.name != 'empid']
super().save(*args, **kwargs)
Это работает, используя преимущества того, как Django заполняет свое sql-предложение в django / db / models / base.py (525). Если у кого-то есть способ лучше или он может объяснить, почему это плохая практика, я буду рад это услышать!