Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django中实现多值属性?_Python_Django_Database_Legacy Database - Fatal编程技术网

Python 如何在Django中实现多值属性?

Python 如何在Django中实现多值属性?,python,django,database,legacy-database,Python,Django,Database,Legacy Database,我有一个包含以下表的旧数据库: 人 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

我有一个包含以下表的旧数据库:

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
每个人都可以有零个或多个电话号码,这是person实体的多值属性

我尝试使用Django的inspectdb命令,该命令生成了以下models.py:

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'),)
但是,当我尝试保存PhoneNumber的新实例时,Django返回以下错误消息:

django.db.utils.ProgrammingError: column phonenumbers.id does not exist
显然,Django希望电话号码的表中有一个代理键。 由于电话号码表不是一个实体,它在我的旧数据库中没有代理项。请注意,phonenumbers的表主键是其所有列的组合

如何将这些表映射到Django的模型中,以便它与我的旧数据库一起工作?

在Django中,所有模型(为您编写的或使用inspectdb生成的)

如果您想像使用模型一样使用表电话号码,则需要此表具有主键


在这种情况下,我的建议是修改旧表以手动添加新的主键,并放弃复合主键。您的旧表有一个复合主键(phone\u number+area\u code),Django不正式支持此功能。

Django不支持复合主键,并且您的PhoneNumbers表有一个跨越三列的主键。这已经开放多年了。有一个提供复合主键支持的版本,但是它已经两年没有维护了,并且与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
请注意,我已经亲自重命名了主键字段。这只是表面上的改变。这是因为约定将主键字段作为id。当您处理许多模型时,您可能会忘记此模型的主键的名称不同。因此发生了变化