在 Postgres/PostGIS 中迁移 django 模型不反映

Posted

技术标签:

【中文标题】在 Postgres/PostGIS 中迁移 django 模型不反映【英文标题】:Migrating django models in Postgres/PostGIS not reflecting 【发布时间】:2018-03-22 13:19:48 【问题描述】:

我使用 ogr2ogr 成功地将我的 Geojson 数据导入到 PostGIS。

我运行以下命令:python manage.py inspectdb

class Route(models.Model):
   ogc_fid = models.AutoField(primary_key=True)
   distance = models.FloatField(blank=True, null=True)
   route_type = models.CharField(max_length=-1, blank=True, null=True)
   route_long = models.CharField(max_length=-1, blank=True, null=True)
   route_name = models.CharField(max_length=-1, blank=True, null=True)
   agency_id = models.ForeignKey(max_length=-1, blank=True, null=True)
   route_id = models.CharField(max_length=-1, blank=True, null=True)
   route_url = models.CharField(max_length=-1, blank=True, null=True)
   route_desc = models.CharField(max_length=500, blank=True, null=True)
   duration = models.FloatField(blank=True, null=True)
   shape_id = models.IntegerField(blank=True, null=True)
   route_tcolor = models.CharField(max_length=-1, blank=True, null=True)
   route_color = models.CharField(max_length=-1, blank=True, null=True)
   wkb_geometry = models.LineStringField(blank=True, null=True)

class Meta:
    managed = False
    db_table = 'network_route'

当然,我必须将max_length 修改为正整数并将manage 设置为True,所以我这样做了。

我还添加了一个额外的列,created_atupdated_at

产生以下最终模型:

class Route(models.Model):
   ogc_fid = models.AutoField(primary_key=True)
   distance = models.FloatField(blank=True, null=True)
   route_type = models.CharField(max_length=100, blank=True, null=True)
   route_long = models.CharField(max_length=200, blank=True, null=True)
   route_name = models.CharField(max_length=100, blank=True, null=True)
   agency_id = models.ForeignKey(Agency, on_delete=models.CASCADE)
   route_id = models.CharField(max_length=100, blank=True, null=True)
   route_url = models.CharField(max_length=300, blank=True, null=True)
   route_desc = models.CharField(max_length=500, blank=True, null=True)
   duration = models.FloatField(blank=True, null=True)
   shape_id = models.IntegerField(blank=True, null=True)
   route_tcolor = models.CharField(max_length=100, blank=True, null=True)
   route_color = models.CharField(max_length=100, blank=True, null=True)
   wkb_geometry = models.LineStringField(blank=True, null=True)

   created_at = models.DateTimeField(default=timezone.now(),editable=False)
   updated_at = models.DateTimeField(blank=True, null=True)

   objects = models.GeoManager()

class Meta:
    managed = True
    db_table = 'network_route'

def save(self, *args, **kwargs):
    #On save, update timestamps
    if not self.id:
        self.created_at = timezone.now()
    self.updated_at = timezone.now()
    return super(Route, self).save(*args, **kwargs)

def __str__(self):
    return self.route_id

我运行:makemigrations [appname],它只检测到 Meta - Change Meta options on route 的变化

如何在模型中添加其他更改,例如 created_atupdated_at 被迁移捕获?

我做错了吗?

【问题讨论】:

您是否正在尝试更新一些遗留代码?您有必须保存的数据库吗? @JohnMoutafis 很好,是的。但实际上我可以重做这一切,因为我还在设置它。但是,我的问题在于,例如,如果我需要在我的模型中添加另一个字段,我该如何防止重新做一遍? 嘿,@Reiion 我想知道,我的回答有帮助吗?你的问题解决了吗? @JohnMoutafis 嘿!对不起,我现在真的要试试了。我今天才能够回到它。 【参考方案1】:

问题一定出自您的旧代码中的该行:managed = False。虽然有一些选项可以解决您的问题:

    简单(干净的)方式:

    既然你可以重建你的数据库并且你没有任何东西是你不能没有的,那就抹去一切,然后重新开始。

    删除迁移文件夹中除 __init__.py 之外的所有内容。 擦除您的数据库并重新创建它。 ./manage.py makemigrations./manage.py migrate

    好吧,你会失去一切,但这是“白纸黑字”的方法。

    (可能)更好的方法:

    打开您的上一次迁移(使用makemigrations 命令进行的迁移)并手动编写其余部分:

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    import django.utils.timezone
    from django.db import migrations, models
    
    
    class Migration(migrations.Migration):
        dependencies = [
            ('your_app', 'your_previous_migration'),
        ]
    
        operations = [
            # That takes care of you Meta changes 
            migrations.AlterModelOptions(
                name='route',
                options=
                    'managed': True, 
                    'table': 'network_route', 
                ,
            ),
            # That will add the created_at field
            migrations.AddField(
                model_name='route',
                name='created_at',
                field=models.DateTimeField(
                    default=django.utils.timezone.now,
                    editable=False
                ),
            ),
            # That will add the updated_at field
            migrations.AddField(
                model_name='route',
                name='updated_at',
                field=models.DateTimeField(blank=True, null=True),
       ]
    

    现在您可以尝试使用 ./manage.py migrate 进行迁移,这应该可以解决问题!

【讨论】:

我尝试了第一个。第二个看起来也可行。但是在模型中添加新字段时,我必须始终对其进行编辑。如果我删除一个字段,它会反映出来。所以这实际上是我的问题。 :(

以上是关于在 Postgres/PostGIS 中迁移 django 模型不反映的主要内容,如果未能解决你的问题,请参考以下文章

Postgres 字符串前的“E”是啥?

Postgres 中的动态 UNION ALL 查询

--fake-initial vs --fake 在 Django 迁移中?

在 FROM 子句中创建大型虚拟表

电音中DJ/Producer/MC/EDM/Remix/Mix的名词解释(转)

怎么把一首自己喜欢的普通歌曲变成DJ 混合DJ?