2015-05-04 108 views
0

我有很多外键定义的问题,我有inspectdb'd到我的models.py文件中。Django - 遗留MySQL数据迁移错误

我有一组,我想纳入我的Django应用程序的遗留表的,所以我跑了python manage.py inspectdb > models.py

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

MySQL的CREATE TABLE语句:

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 

这里是车型

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被定义了两次。

更改

id = models.Autofield() 
... 
host = models.CharField(max_length=24) 

id = models.Autofield(primary_key=True) 
... 
host = models.CharField(primary_key=True, max_length=24) 

让Django的不知道去创造自己的ID字段。我仍然不确定它是否正确处理共享密钥。


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

related_name添加到其中一个外键似乎可以阻止投诉。

我改变

host = models.ForeignKey(Gps, db_column='host') 

host = models.ForeignKey(Gps, db_column='host', related_name='gps_zda_host_fk') 

再一次,我不知道这是妥善处理共享外键。


3. 为了做一些测试,我决定加入模型admin.py中,看看领域得到适当填充。

这导致发现更多问题。

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

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


4. 再次在管理,我无法正常加载gps_zda对象。起初,我抱怨一个不存在的gps_zda.id列错误。我能够通过改变

host = models.ForeignKey(Gps, db_column='host', related_name='gps_zda_host_fk') 
... 
gps = models.ForeignKey(Gps) 

来解决这个问题,以

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', '主机'),)到类元为GpsZda。

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


当我开始看Django时,我认为它会很有趣。没那么多。我真的质疑将任何现有数据库移入Django项目的可行性。

这里是我目前的模式。任何关于如何让他们更好地与我的桌子搭配的建议都会受到欢迎。

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'),) 

回答

1

Django当前不支持表中的组合主键。 (见wiki page和缺乏model meta options这是这将被定义的地方。)

最好的选择可能是另一个识别栏添加到您的gps表,所以Django的可以用它正常工作。

至于其他的问题,如果你研究和他们交不同的问题,可能是最好的。