MSSQLでレガシーDBを使用しています。問題を引き起こしている2つの列を持つテーブルがあります。
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列があり、djangoによって生成されるSQL更新コードの関連部分は次のとおりです。
UPDATE [EMP] SET [EMPID] = 399,
.........
WHERE [EMP].[SSN] = 2509882579
問題は、EMP.EMPIDがMSSQLのIDフィールドであるため、既存の従業員に変更を保存しようとすると、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をIDとして持つことは、プログラムにとって重要ではないため、一時的な列を作成してそれを削除し、コピー、削除、名前変更を行うことは論理的なことのように思われます。これにより、古い顧客をDjangoに転送するための追加の手順が1つ作成されるので、私の質問は、このテーブルを更新するたびにDjangoが「[EMPID] = XXX」スニペットを生成しないようにする方法はありますか?
編集
私はこのように私のモデルにパッチを当てました:
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がdjango / db / models / base.py(525)のsql-sentenceに入力する方法を利用して機能します。誰かがより良い方法を持っているか、これが悪い習慣である理由を説明できるなら、私はそれを聞いてうれしいです!