【问题标题】:Django South - table already existsDjango South - 表已经存在
【发布时间】:2011-03-06 15:51:53
【问题描述】:

我正在尝试从 South 开始。我有一个现有的数据库,我添加了 South (syncdb, schemamigration --initial)。

然后,我更新了models.py 以添加一个字段并运行./manage.py schemamigration myapp --auto。它似乎找到了这个领域,并说我可以用./manage.py migrate myapp 应用它。但是,这样做给出了错误:

django.db.utils.DatabaseError: table "myapp_tablename" already exists

tablenamemodels.py 中列出的第一个表。

我正在运行 Django 1.2,South 0.7

【问题讨论】:

    标签: django django-south


    【解决方案1】:

    由于您已经在数据库中创建了表,您只需将初始迁移作为假运行

    ./manage.py migrate myapp --fake
    

    确保模型的架构与数据库中表的架构相同。

    【讨论】:

    • 知道了,谢谢。它实际上是迁移而不是架构迁移,但您的回答让我朝着正确的方向前进。
    • 我的错误只是从 OP 复制了命令,正确的命令 ./manage.py migrate myapp --fake
    • 这个解决方案并没有解决我的问题。我没有修改数据库并崩溃了一些视图,因为该字段不是在表上创建的。我不得不评论新属性,再次使用假迁移以重新建立一切,我第二次尝试它确实有效,但我仍然不明白...... :)
    • @Ashok 也许您还应该指定我们必须在migrate 之前重做schemamigration,以防我们在最后一个schemamigration 之前已经进行了修改。
    • 这对我没有帮助。我的数据库中已经有一个表,并且在伪造迁移之后,无法添加其他伪造的表。我不得不放弃所有桌子并重新开始。
    【解决方案2】:

    虽然表“myapp_tablename”已经存在错误停止提升 在我做了 ./manage.py migrate myapp --fake 之后,DatabaseError 显示 没有这样的列:myapp_mymodel.added_field。

    遇到了完全相同的问题!

    1.首先检查导致此问题的迁移编号。假设它是:0010。

    2.您需要:

    ./manage.py schemamigration myapp --add-field MyModel.added_field
    ./manage.py migrate myapp
    

    如果缺少多个字段,您必须为每个字段重复。

    3.现在您获得了一堆新的迁移,因此请从 myapp/migrations 中删除他们的文件(如果您需要添加多个字段,则为 0011 和进一步)。

    4.运行这个:

    ./manage.py migrate myapp 0010
    

    现在试试 ./manage.py migrate myapp

    如果它没有失败,你就准备好了。只需仔细检查是否缺少任何字段。

    编辑:

    当您有一个安装 South 的生产数据库并且在其他环境中创建的第一个初始迁移复制了您在数据库中已有的内容时,也会出现此问题。这里的解决方案要容易得多:

    1. 伪造第一次迁移:

      ./manage migrate myapp 0001 --fake

    2. 与其余迁移一起滚动:

      ./manage migrate myapp

    【讨论】:

      【解决方案3】:

      当我遇到这个错误时,它有不同的原因。

      就我而言,South 不知何故在我的数据库中留下了一个临时空表,用于_remake_table()。可能我以不应该的方式中止了迁移。在任何情况下,每个后续的新迁移,当它调用 _remake_table() 时,都会抛出错误 sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists,因为它确实已经存在并且不应该存在。

      我觉得 _south_new 有点奇怪,所以我浏览了我的数据库,看到了表 _south_new_myapp_mymodel,挠了挠头,看了看 South's source,认为它是垃圾,丢弃了表,一切都很好。

      【讨论】:

      • 这就是我所看到的,如果我发现了这个,我会省去半个小时的脑痛。非常不愉快 - 但这些是临时迁移表,并且在迁移失败期间留下,可能是为了检查。由于迁移尝试期间的一些数据库完整性问题,发生了我的问题。
      • 这需要更高!如果您使用的是没有架构事务的数据库,这很容易发生
      【解决方案4】:

      如果您的模型与数据库不匹配有问题,例如@pielgrzym,并且您希望自动迁移数据库以匹配最新的 models.py 文件(并删除在@期间不会被夹具重新创建的任何数据987654321@):

      manage.py schemamigration myapp --initial
      manage.py migrate myapp --fake
      manage.py migrate myapp zero
      manage.py migrate myapp
      

      这只会删除并重新创建存在于您最新的models.py 文件中的数据库表,因此您的数据库中可能有来自以前的syncdbs 或migrates 的垃圾表。要摆脱这些,请在所有这些迁移之前添加:

      manage.py sqlclear myapp | manage.py sqlshell
      

      如果这仍然在您的数据库中留下一些 CRUFT,那么您必须先创建一个 inspectdb 并从中创建 models.py 文件(用于您要清除的表和应用程序),然后再执行sqlclear 然后在创建 --initial 迁移并迁移到它之前恢复您的原始 models.py。所有这些都是为了避免弄乱数据库所需的特定 SQL 风格。

      【讨论】:

        【解决方案5】:

        Perform these steps in order may help you:

        1) python manage.py schemamigration apps.appname --initial

        以上步骤默认创建迁移文件夹。

        2) python manage.py migrate apps.appname --fake

        生成虚假迁移。

        3) python manage.py schemamigration apps.appname --auto

        然后你可以根据需要添加字段并执行上述命令。

        4) python manage.py migrate apps.appname

        【讨论】:

          【解决方案6】:

          如果您有现有的数据库和应用程序,您可以使用南转换命令

          ./manage.py convert_to_south myapp
          

          这必须在您对数据库中已有的内容进行任何更改之前应用

          convert_to_south 命令仅在您运行它的第一台机器上完全有效。一旦你提交了它在你的 VCS 中所做的初始迁移,你必须在每台拥有代码库副本的机器上运行./manage.py migrate myapp 0001 --fake(首先确保它们是最新的模型和模式)。 参考:http://south.readthedocs.org/en/latest/convertinganapp.html

          【讨论】:

            【解决方案7】:

            作为临时解决方案,您可以在迁移脚本中注释表创建。

            class Migration(migrations.Migration):
            
                dependencies = [
                    (...)
                ]
            
                operations = [
                    #migrations.CreateModel(
                    #    name='TABLE',
                    #    fields=[
                    #            ....
                    #            ....
                    #    ],
                    #),
                    ....
                    ....
            

            或者

            如果现有表不包含任何行(空),则考虑删除如下表。 (仅当表不包含行时才建议使用此修复程序)。还要确保在 createModel 操作之前进行此操作。

            class Migration(migrations.Migration):
            
                dependencies = [
                    (...),
                ]
            
                operations = [
                    migrations.RunSQL("DROP TABLE myapp_tablename;")
                ]
            

            【讨论】:

              【解决方案8】:

              另一种解决方案(可能是临时解决方案)。

              $ python manage.py sqlmigrate APP_NAME MIGRATION_NAME
              

              例如.,.

              $ python manage.py sqlmigrate users 0029_auto_20170310_1117
              

              这将列出原始 sql 查询中的所有迁移。您可以选择要运行的查询,避免创建现有表的部分

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-03-31
                • 2016-06-12
                • 2012-06-01
                • 2012-03-11
                • 2019-11-17
                • 2011-06-20
                • 2013-02-22
                相关资源
                最近更新 更多