MySQL 数据库中指定的两个主键

问题描述 投票:0回答:3

我正在尝试创建一个测试数据库,它是预先存在的数据库的副本。我正在使用 Django 模型(理论上是与原始数据库一起使用的模型)来执行此操作。我最近从其他人那里继承了代码,并试图弄清楚代码到底发生了什么。

在模型中,其中一张表有两列被标识为主键。

        column1 = models.IntegerField(primary_key = True)
        column2 = models.IntegerField(primary_key = True)
        column3 = models.CharField(max_length = 30)

当我尝试将此模型同步到测试数据库时 - 发生错误:

文件“/somePathHere/MySQLdb/connections.py”,第36行,在defaulterrorhandler中引发错误类,错误值 _mysql_exceptions.OperationalError: (1068, '定义了多个主键')

django docs中写到Django不允许多个主键。然而,看看原始 MySQL 数据库中

DESCRIBE [tablename]
的输出,看起来这正是这里发生的事情 :

        +------------+------------+------+-----+---------+-------+
        | Field      | Type       | Null | Key | Default | Extra |
        +------------+------------+------+-----+---------+-------+
        | IDENTIFIER | bigint(20) | NO   | PRI | NULL    |       |
        | TIMESTAMP_ | bigint(20) | NO   | PRI | NULL    |       |
        | VALUE_     | longtext   | YES  |     | NULL    |       |
        +------------+------------+------+-----+---------+-------+

请注意,IDENTIFIER 和 TIMESTAMP_ 都被列为主键。

我看到很多关于基于多列创建主键的主题(示例 1示例 2示例 3) - 我看到的是复合键吗?在这种情况下,如何通过 Django 模型进行转发,即如何复制它?

如果不是复合键,那是什么?

mysql django model primary-key mysql-error-1068
3个回答
4
投票

Django 不支持它,但有一个解决方法。在您的模型上指定 unique_together 和元部分中的字段:

class MyClass(models.Model):
    IDENTIFIER = models.IntegerField(blank=False,null=False)
    TIMESTAMP_ = models.IntegerField(blank=False,null=False)
    VALUE_ = models.TextField(blank=True, null=True)

    class Meta:
        unique_together = ('IDENTIFIER', 'TIMESTAMP_')

这将保留两列主键行为。


3
投票

Django 目前不支持多列主键,尽管有补丁/分叉可以扩展它(具有不同程度的改进)。来自常见问题解答“Django 模型支持多列主键吗?”:

不。仅支持单列主键。

但这在实践中不是问题,因为没有什么可以阻止您添加其他约束(使用

unique_together
模型选项或直接在数据库中创建约束),并在该级别强制执行唯一性。管理界面等功能需要单列主键才能工作;例如,您需要一种简单的方法来指定要编辑或删除的对象。

您看到的不是两个主键,而是一个两列主键。表根据定义只能有一个主键。


2
投票

它是一个复合主键。尝试执行这个:

show create table mytable;

它应该显示复合键的定义。

从 mysql 的角度来看,这并不是什么“不寻常”的事情。

© www.soinside.com 2019 - 2024. All rights reserved.