【问题标题】:Migrating django sqlite database to postgresql将 django sqlite 数据库迁移到 postgresql
【发布时间】:2016-09-04 18:45:04
【问题描述】:

自从我投入生产以来,我一直在尝试将 sqlite 数据库迁移到更稳定的 postgresql。我遇到了一些问题,但我遇到了障碍,无法继续前进。

为了获得备份,我使用 settings.py 中配置的 sqlite 运行了 ./manage.py dumpdata --exclude auth.permission --exclude contenttypes --natural-foreign > db.json

配置好 postgresql 数据库后,我运行了 ./manage.py migrate,并在 settings.py 中配置了 postgresql。

最后我跑了./manage.py loaddata db.json,得到了以下错误:

django.db.utils.ProgrammingError: Problem installing fixture '/home/ubuntu/bl/loom/db.json': Could not load web.Project(pk=18): operator does not exist: character varying = integer
LINE 1: ...INNER JOIN "web_project_tags" ON ("web_tag"."tag" = "web_pro...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

错误所指的模型具有以下代码:

class Project(models.Model):
    owner = models.ForeignKey(User, related_name='owner')
    name = models.CharField(max_length=50)
    img = models.ImageField("Cover", upload_to="img/projects", blank=True, null=True)
    vid = models.URLField("Youtube Link", null=True, blank=True)
    desc = models.TextField("Description", max_length=500)
    stakeholders = models.ManyToManyField(Profile, related_name='stakeholders', blank=True)
    industry = models.ManyToManyField(Industry, related_name="industry")
    tags = models.ManyToManyField(Tag, related_name="project_tag")
    is_private = models.BooleanField("Is this a private project?", default=False, help_text="Private projects are not shown on the index.")
    b_type = models.ForeignKey(B_type, help_text="What type of project is this")
    role = models.ForeignKey(Role, related_name="role")
    deleted = models.BooleanField(default=False)

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name = "Project"
        verbose_name_plural = "Projects"

class Tag(models.Model):
    tag = models.CharField("Tag", max_length=100, primary_key =True)

    def __unicode__(self):
        return self.tag

    class Meta:
        verbose_name = "Tag"
        verbose_name_plural = "Tags"

更新: 日志文件包含更详细的错误并显示完整的查询。

2016-05-09 00:54:39 UTC ERROR: operator does not exist: 
character varying = integer at character 89 
2016-05-09 00:54:39 UTC HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
2016-05-09 00:54:39 UTC STATEMENT: SELECT "web_tag"."tag" FROM "web_tag" INNER JOIN "web_project_tags" ON ("web_tag"."tag" = "web_project_tags"."tag_id") WHERE "web_project_tags"."project_id" = 18

【问题讨论】:

  • 错误信息告诉你web_tag.tag是一个字符串但是web_project_tags中的对应列是一个整数,你不能在PostgreSQL中说varchar_column = integer_column。您的标签关系存在类型问题。抱歉,我对 Python/Django 了解的不够多,无法告诉你如何解决它。
  • 您的文件似乎没有以 JSON 格式导出。看起来您创建的是一个 SQL 转储。最不寻常的,因为默认格式是 JSON。请务必提取错误中提到的行并将其添加到它的任一侧。
  • 我确实检查了转储,它被导出为 json。该文件确实开始加载,但有@mu-is-too-short 提到的问题。我想应该有一种方法可以按照错误提示转换列,但我似乎无法找到方法。
  • 你能把postgresql创建的实际表贴在这里吗?以及图像中的完整错误。目前尚不清楚正在连接哪些列。如果 django 没有向您显示完整的错误,您将在 postgresql 日志中找到它(位置取决于您的操作系统)
  • 这是日志中的错误:2016-05-09 00:54:39 UTC ERROR: operator does not exist: character varying = integer at character 89 2016-05-09 00:54:39 UTC HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 2016-05-09 00:54:39 UTC STATEMENT: SELECT "web_tag"."tag" FROM "web_tag" INNER JOIN "web_project_tags" ON ("web_tag"."tag" = "web_project_tags"."tag_id") WHERE "web_project_tags"."project_id" = 18

标签: python django database postgresql sqlite


【解决方案1】:

我终于解决了这个问题,希望这个答案对某人有所帮助。

检查日志后,我检查了 postgresql 数据库中的表,它引发了错误。事实证明,即使迁移到最新版本,web_project_tags 的数据类型也不正确。我使用以下方法更正了此数据类型:

ALTER TABLE problematic_table ALTER COLUMN problematic_column TYPE character varying(100);

我最终用./manage.py loaddata db.json加载了数据并且没有更多错误。

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 2021-09-21
    • 1970-01-01
    • 2016-11-08
    • 2018-10-13
    • 2013-04-05
    • 2018-08-01
    • 2011-07-16
    • 2018-05-23
    相关资源
    最近更新 更多