4

我一直在用 south 开发一个 django 应用程序,并进行了一种松散的持续部署。初次迁移后不久,我进行了几次数据迁移,如下所示:

def forwards(self, orm):                                                   
    from django.core.management import call_command                        
    call_command("loaddata", "#######.json")    

当时,我什么都没想。手动填充数据库然后将其全部转储到固定装置中已经很容易了。然后当我终于写了一些单元测试时,我开始收到这样的错误:

Creating test database for alias 'default'...
Problem installing fixture '/home/axel/Workspace/02_ereader_blast/content/fixtures/99_deals.json': Traceback (most recent call last):
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 196, in handle
    obj.save(using=using)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/serializers/base.py", line 165, in save
    models.Model.save_base(self.object, using=using, raw=True)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/base.py", line 551, in save_base
    result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/manager.py", line 203, in _insert
    return insert_query(self.model, objs, fields, **kwargs)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 1593, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 910, in execute_sql
    cursor.execute(sql, params)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 52, in execute
    return self.cursor.execute(query, args)
DatabaseError: Could not load content.BookDeal(pk=1): column "entry_id" of relation "content_bookdeal" does not exist
LINE 1: INSERT INTO "content_bookdeal" ("id", "book_id", "entry_id",...
                                                         ^


Installed 19 object(s) from 1 fixture(s)
Problem installing fixture '/home/axel/Workspace/02_ereader_blast/content/fixtures/99_deals_entries.json': Traceback (most recent call last):
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 190, in handle
    for obj in objects:
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/serializers/json.py", line 47, in Deserializer
    raise DeserializationError(e)
DeserializationError: Entry has no field named 'book_deals'

据我所知,loaddata 命令使用的是我最近的模型,而不是当时的南方州,并且因为从那时起我已经对它们进行了重大更改,因此当前模型将旧数据解释为无效。

所以我的问题是:

  • 设置未来数据迁移以免发生这种情况的最佳方法是什么?
  • 我如何才能摆脱这种情况,并将其带到最佳实践领域?
4

2 回答 2

2

我找到了解决方案,由这个 stackoverflow 问题提供:

django 在向后迁移/ loaddata 后从夹具加载数据使用的是模型模式而不是数据库模式

如最佳答案中所述,我使用了一个非常优雅地修补 loaddata 命令获取其模型的片段。

请注意,我确实必须扩大我对这些数据迁移的冻结范围,以便他们可以从 orm 而不是直接访问他们需要的所有模型。

这感觉像是解决问题的正确方法。

于 2013-02-22T21:55:19.940 回答
0

我认为,我的方法很可能是完全的黑客/滥用南方/最糟糕的做法。但是...如果您知道您的 django 模型符合您的数据表。我可能会采用新的开始方法:

  1. 重命名(或删除)相关迁移文件夹。
  2. 在 south_migrationhistory 数据表中,删除您尝试为其创建新开始的应用程序的所有关联条目。
  3. python manage.py convert_to_south app-name.
  4. 一切都应该很好。

如果数据表是规范的,并且您的 django 模型不符合要求,那么我将 django 模型与数据表保持一致的方式是运行:

python manage.py inspectdb > inspectdb.py

现在我可以为我的模型比较两个版本的 django 代码,以使它们对齐。这使我能够经历新的开始序列。

于 2013-02-22T21:07:23.603 回答