I work with an obsolete database in MSSQL. We have a table with two columns that cause me problems:
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')
Thus, the table has the ssn column as the primary key, and the corresponding part of the SQL update code generated by django is as follows:
UPDATE [EMP] SET [EMPID] = 399, ......... WHERE [EMP].[SSN] = 2509882579
The problem is that EMP.EMPID is an identification field in MSSQL, and so pyodbc throws this error whenever I try to save changes to an existing employee:
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)")
The presence of EMP.EMPID as a person is not critical for anything in the program, so deleting it by creating a temporary column and copying, deleting, renaming seems logical. This creates one additional step when migrating old clients to Django, so my question is, is there a way to prevent Django from generating the fragment [[EMPID] = XXX] when I do the update in this table?
EDIT
I fixed my model as follows:
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)
This works by taking advantage of the way Django populates this sql statement in django / db / models / base.py (525). If someone has a better way or can explain why this is bad practice, I would be happy to hear that!