首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Django -遗留MySQL数据迁移错误

Django -遗留MySQL数据迁移错误
EN

Stack Overflow用户
提问于 2015-05-04 20:05:55
回答 1查看 148关注 0票数 0

我对外键定义有很多问题,我把inspectdbd放到了models.py文件中。

我有一组遗留表,我想将这些表合并到Django应用程序中,所以我运行了python manage.py inspectdb > models.py

有7个GPS表,我想在我的应用程序中使用。看其中的两个就能充分描述我遇到的问题。

MySQL创建表语句:

代码语言:javascript
代码运行次数:0
运行
复制
CREATE TABLE `gps` (
  `longitude_dir` char(1) DEFAULT NULL,
  `longitude` decimal(8,5) DEFAULT NULL,
  `latitude` decimal(7,5) DEFAULT NULL,
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `host_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `latitude_dir` char(1) DEFAULT NULL,
  `host` varchar(24) NOT NULL,
  `altitude_units` char(1) DEFAULT NULL,
  `gps_time` datetime DEFAULT NULL,
  `raw` blob NOT NULL,
  `clean` bit(1) DEFAULT NULL,
  `data_valid` bit(1) DEFAULT NULL,
  `modem` varchar(15) NOT NULL,
  `altitude` decimal(7,2) DEFAULT NULL,
  PRIMARY KEY (`id`,`host`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

CREATE TABLE `gps_zda` (
  `local_zone_minutes` tinyint(4) DEFAULT NULL,
  `host` varchar(24) NOT NULL,
  `year` tinyint(4) DEFAULT NULL,
  `day` tinyint(4) DEFAULT NULL,
  `month` tinyint(4) DEFAULT NULL,
  `local_zone` tinyint(4) DEFAULT NULL,
  `gps_id` int(10) unsigned NOT NULL,
  `timestamp` time DEFAULT NULL,
  KEY `gps_fk_zda` (`gps_id`,`host`),
  CONSTRAINT `gps_fk_zda` FOREIGN KEY (`gps_id`, `host`) REFERENCES `gps` (`id`, `host`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

下面是模型的子集

代码语言:javascript
代码运行次数:0
运行
复制
from __future__ import unicode_literals

from django.db import models


class Gps(models.Model):
    longitude_dir = models.CharField(max_length=1, blank=True, null=True)
    longitude = models.DecimalField(max_digits=8, decimal_places=5, blank=True, null=True)
    latitude = models.DecimalField(max_digits=7, decimal_places=5, blank=True, null=True)
    id = models.AutoField()
    host_time = models.DateTimeField()
    latitude_dir = models.CharField(max_length=1, blank=True, null=True)
    host = models.CharField(max_length=24)
    altitude_units = models.CharField(max_length=1, blank=True, null=True)
    gps_time = models.DateTimeField(blank=True, null=True)
    raw = models.TextField()
    clean = models.TextField(blank=True, null=True)  # This field type is a guess.
    data_valid = models.TextField(blank=True, null=True)  # This field type is a guess.
    modem = models.CharField(max_length=15)
    altitude = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'gps'
        unique_together = (('id', 'host'),)

class GpsZda(models.Model):
    local_zone_minutes = models.IntegerField(blank=True, null=True)
    host = models.ForeignKey(Gps, db_column='host')
    year = models.IntegerField(blank=True, null=True)
    day = models.IntegerField(blank=True, null=True)
    month = models.IntegerField(blank=True, null=True)
    local_zone = models.IntegerField(blank=True, null=True)
    gps = models.ForeignKey(Gps)
    timestamp = models.TimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'gps_zda'
  1. 因此,我在尝试python manage.py makemigrations时遇到的第一个问题是,(gps.id, gps.host)没有被正确地定义为主键。事实上,似乎许多违禁品都被忽视了。一开始我收到一个错误,说gps.id被定义了两次。

改变

代码语言:javascript
代码运行次数:0
运行
复制
id = models.Autofield()
...
host = models.CharField(max_length=24)

代码语言:javascript
代码运行次数:0
运行
复制
id = models.Autofield(primary_key=True)
...
host = models.CharField(primary_key=True, max_length=24)

让django知道不要创建它自己的id字段。我仍然不确定它是否正确地处理共享密钥。

  1. 第二个问题是试图运行makemigrations,因为gps_zda表有一个共享的、唯一的外键。Django抱怨说,它不知道如何命名第二个外键。

在其中一个外键中添加一个related_name似乎可以阻止抱怨。

我改变了

代码语言:javascript
代码运行次数:0
运行
复制
host = models.ForeignKey(Gps, db_column='host')

代码语言:javascript
代码运行次数:0
运行
复制
host = models.ForeignKey(Gps, db_column='host', related_name='gps_zda_host_fk')

再一次,我不确定这是否正确地处理共享外键。

  1. 为了进行一些测试,我决定将模型添加到admin.py中,并查看字段是否被正确填充。

这导致了更多问题的发现。

问题3.当我打开一个gps object时,我看到位字段(gps.clean,gps.data_valid)被转换为TextFields。我试图通过简单地将TextField更改为NullBooleanField来快速修复这些问题。现在,在管理页面上,我看到一个适当的下拉选项:未知,是,不是。不幸的是,现有的位值1被解析为未知。

我不知道如何解决这个问题,尝试改变数据库结构会有问题。

  1. 再次在管理中,我无法正确地加载gps_zda对象。一开始,我收到一个错误,抱怨一个不存在的gps_zda.id列。我可以通过改变
代码语言:javascript
代码运行次数:0
运行
复制
host = models.ForeignKey(Gps, db_column='host', related_name='gps_zda_host_fk')
...
gps = models.ForeignKey(Gps)

代码语言:javascript
代码运行次数:0
运行
复制
host = models.ForeignKey(Gps, primary_key=True, db_column='host', related_name='gps_zda_host_fk')
...
gps = models.ForeignKey(Gps, primary_key=True)

这让Django知道不要寻找gps_zda.id字段。

我还将`unique_together = (('gps','host')添加到GpsZda的Meta类中。

但是,我仍然无法通过管理页面查看gps_zda数据。我收到以下错误gps zda object with primary key u'Arthur' does not exist.,其中Arthur是一个有效的gps.host值。

当我开始看Django的时候,我觉得这会很有趣。不是很多。我真的怀疑将任何现有数据库转移到Django项目中是否可行。

这是我现在的型号。任何关于我如何使他们更好地使用我的桌子的建议都将受到欢迎。

代码语言:javascript
代码运行次数:0
运行
复制
class Gps(models.Model):
    longitude_dir = models.CharField(max_length=1, blank=True, null=True)
    longitude = models.DecimalField(max_digits=8, decimal_places=5, blank=True, null=True)
    latitude = models.DecimalField(max_digits=7, decimal_places=5, blank=True, null=True)
    id = models.AutoField(primary_key=True)
    host_time = models.DateTimeField(primary_key=True)
    latitude_dir = models.CharField(max_length=1, blank=True, null=True)
    host = models.CharField(primary_key=True, max_length=24)
    altitude_units = models.CharField(max_length=1, blank=True, null=True)
    gps_time = models.DateTimeField(blank=True, null=True)
    raw = models.TextField()
    clean = models.NullBooleanField(null=True)  # This field type is a guess.
    data_valid = models.NullBooleanField(null=True)  # This field type is a guess.
    modem = models.CharField(max_length=15)
    altitude = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'gps'
        unique_together = (('id', 'host'),)

class GpsZda(models.Model):
    local_zone_minutes = models.IntegerField(blank=True, null=True)
    host = models.ForeignKey(Gps, db_column='host', related_name='gps_zda_host_fk')
    year = models.IntegerField(blank=True, null=True)
    day = models.IntegerField(blank=True, null=True)
    month = models.IntegerField(blank=True, null=True)
    local_zone = models.IntegerField(blank=True, null=True)
    gps = models.ForeignKey(Gps, primary_key=True, unique=True)
    timestamp = models.TimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'gps_zda'
        unique_together = (('gps', 'host'),)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-04 22:41:29

Django目前不支持表中的复合主键。(请参见wiki页面和缺乏模型元选项,这是要定义的位置。)

最好的选择可能是向您的gps表中添加另一个标识列,这样Django可以正确地使用它。

对于其他的问题,最好是你为他们研究和张贴单独的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30039002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档