テスト中にこれが見つかりました。1 台のマシンはデフォルト エンジンとして MyISAM を使用してセットアップされ、もう 1 台はデフォルト エンジンとして InnoDB を使用してセットアップされました。次のようなコードがあります
class StudyManager(models.Manager):
def scored(self, school=None, student=None):
qset = self.objects.all()
if school:
qset = qset.filter(school=school)
if student:
qset = qset.filter(student=student)
return qset.order_by('something')
問題のコードは次のようになります。
print Study.objects.scored(student).count()
つまり、「学生」は学校として扱われていました。これは、MyISAM がロールバックを実行できず、テストごとに完全に再作成されるため (autoincrement id フィールドをリセットする)、student.id == school.id であるため、MyISAM でのテストを通じて得られました。ロールバックは明らかに自動インクリメント フィールドをリセットしないため、InnoDB はこれらのエラーを検出しました。
id
問題は、テスト中に、すべてのモデルにフィールドがあるため、ダックタイピングが原因で他の多くのエラーが検出されない可能性があることです。オブジェクトのIDが(本番またはテストで)並んでいることと、それが問題を引き起こしている/バグを見つけられないことが心配です。
次のようにアサートを追加できます。
class StudyManager(models.Manager):
def scored(self, school=None, student=None):
qset = self.objects.all()
if school:
assert(isinstance(school, School))
qset = qset.filter(school=school)
if student:
assert(isinstance(student, Student))
qset = qset.filter(student=student)
return qset.order_by('something')
しかし、これは見栄えが悪く、大変な作業です (元に戻して改造する必要があります)。デバッグモードでも遅くなります。
モデルの id フィールドを強制的に model_id
(学生の場合は学生 ID、学校の場合は school_id)、学校が学生 ID を持たないようにするというアイデアについて考えました。これには主キー フィールドの指定のみが含まれますが、ジャンゴには.pk のショートカットなので、すべての場合に役立つとは限りません。
この種のバグをキャッチするためのよりエレガントなソリューションはありますか? C++ の経験が長いので、タイプ セーフが恋しいです。