Prevent Django from updating identifier column in MSSQL

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') # Field name made lowercase. 

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!

+4
source share
1 answer

This question is old, and Sindri found a workable solution, but I would like to offer a solution that I have been using in production for several years, which does not require courage in _meta .

I had to write a web application integrated with an existing business database containing many calculated fields. These fields, usually calculating the record status, are used for almost every access to the object throughout the application, and Django had to work with them.

These types of fields work with the model manager, which adds the required fields to the query using extra(select=...) .

ComputedFieldsManager snippet: https://gist.github.com/manfre/8284698

 class Emp(models.Model): ssn = models.CharField(_("Social security number"), max_length=10, primary_key=True, db_column=u'SSN') # Field name made lowercase. objects = ComputedFieldsManager(computed_fields=['empid']) # the empid is added on to the model instance Emp.objects.all()[0].empid # you can also search on the computed field Emp.objects.all().computed_field_in('empid', [1234]) 
+3
source

All Articles