5

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に入力する方法を利用して機能します。誰かがより良い方法を持っているか、これが悪い習慣である理由を説明できるなら、私はそれを聞いてうれしいです!

4

1 に答える 1

5

この質問は古いものであり、Sindri は実行可能な解決策を見つけましたが、私が数年間本番環境で使用してきた解決策を提供したいと考えていました_meta

多くの計算フィールドを含む既存のビジネス データベースと統合する Web アプリケーションを作成する必要がありました。通常はレコードのステータスを計算するこれらのフィールドは、アプリケーション全体のほぼすべてのオブジェクト アクセスで使用され、Django はそれらを操作できる必要がありました。

これらのタイプのフィールドは、必要なフィールドをextra(select=...).

ComputedFieldsManagerコード スニペット: 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])
于 2014-01-06T16:03:51.717 に答える