我正在尝试创建一个测试数据库,它是预先存在的数据库的副本。我正在使用 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 模型进行转发,即如何复制它?
如果不是复合键,那是什么?
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_')
这将保留两列主键行为。
Django 目前不支持多列主键,尽管有补丁/分叉可以扩展它(具有不同程度的改进)。来自常见问题解答“Django 模型支持多列主键吗?”:
不。仅支持单列主键。
但这在实践中不是问题,因为没有什么可以阻止您添加其他约束(使用
模型选项或直接在数据库中创建约束),并在该级别强制执行唯一性。管理界面等功能需要单列主键才能工作;例如,您需要一种简单的方法来指定要编辑或删除的对象。unique_together
您看到的不是两个主键,而是一个两列主键。表根据定义只能有一个主键。
它是一个复合主键。尝试执行这个:
show create table mytable;
它应该显示复合键的定义。
从 mysql 的角度来看,这并不是什么“不寻常”的事情。