1

次のテーブルを持つ従来のデータベースがあります。

person_id (PK)  |  first_name  |  last_name
        1       |  John        |  Doe
        2       |  David       |  Bentley

電話番号

person_id (FK,PK) |  phone_number (PK)  | area_code (PK)
        1         |  758-4551           | 909
        1         |  763-3445           | 909
        2         |  634-0011           | 637

すべての人は、0 個以上の電話番号を持つことができます。これは、person エンティティの多値属性です。

次のmodels.pyを生成したDjangoのinspectdbコマンドを使用してみました:

class Person(models.Model):
    person_id = models.BigIntegerField(primary_key=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table = 'person'


class PhoneNumbers(models.Model):
    person = models.ForeignKey(Person, models.DO_NOTHING)
    phone_number = models.CharField(max_length=15)
    area_code = models.CharField(max_length=15)

    class Meta:
        managed = False
        db_table = 'phonenumbers'
        unique_together = (('person', 'phone_number', 'area_code'),)

しかし、PhoneNumbers の新しいインスタンスを保存しようとすると、Django は次のエラー メッセージを返しました。

django.db.utils.ProgrammingError: column phonenumbers.id does not exist

どうやら Django は、電話番号のテーブルに代理キーがあることを期待しています。電話番号のテーブルはエンティティではないため、従来のデータベースには代理キーがありません。phonenumbers テーブルの主キーは、そのすべての列の構成であることに注意してください。

これらのテーブルを Django のモデルにマップして、レガシー データベースで動作させるにはどうすればよいですか?

4

2 に答える 2

1

Django では、すべてのモデル (自分で作成したもの、または inspectdb で生成したもの)は Primary Key を kave する必要があります。

モデルのようにphonenumbersテーブルを使用する場合は、このテーブルに主キーが必要です。

このシナリオでは、レガシー テーブルを変更して新しい主キーを手動で追加し、複合主キーを破棄することをお勧めします。レガシー テーブルには複合主キー ( phone_number + area_code ) があり、これは Django で正式にサポートされていません。

于 2016-06-08T20:13:12.597 に答える
0

Django は複合主キーをサポートしておらず、PhoneNumbers テーブルには 3 つの列にまたがる主キーがあります。このチケットは何年も開いています。複合主キーのサポートを提供するサードパーティのプラグインがありますが、2 年間メンテナンスされておらず、Django の最新バージョンと互換性がありません。

解決策は、主キーを追加することです。しかし、その前に

./manage.py migrate

これにより、django が必要とするテーブルがレガシー データベースに確実に作成されます。

モデルを変更して、この行を削除します

managed = False

これは、モデルへの変更がデータベースに反映されることを django に知らせます。次に、次のようにモデルを変更します。

class Person(models.Model):
    id = models.BigIntegerField(primary_key=True, db_column='person_id')
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    class Meta:
        db_table = 'person'


class PhoneNumbers(models.Model):
    id = models.BigIntegerField(primary_key=True)
    person = models.ForeignKey(Person, models.DO_NOTHING)
    phone_number = models.CharField(max_length=15)
    area_code = models.CharField(max_length=15)

    class Meta:
        db_table = 'phonenumbers'
        unique_together = (('person', 'phone_number', 'area_code'),)

それからする

 ./manage.py makemigrations  your_app_name
 ./manage.py migrate

Person の主キー フィールドの名前を変更したことに注意してください。これは単なる表面的な変更です。これは、主キー フィールドを id とする規則があるためです。多くのモデルを扱っていると、このモデルの主キーの名前が異なっていることを忘れがちです。したがって、変更。

于 2016-06-09T04:04:43.810 に答える