django:South根据平台不会生成相同的索引名称

时间:2014-09-04 16:21:01

标签: mysql linux django windows django-south

我正在研究一个带有MySQL后端的django应用程序。我用south来迁移我的架构。 我刚刚编写了一个删除某些列上的索引的迁移,因为外键更改和所述列的名称更改。 我不想通过“添加列” - >“复制数据” - >“删除旧列”。

所以我的迁移代码块看起来像这样(给一个表的样本):

# Change FK link from 'reference_workobject' to 'assets_asset'
db.delete_foreign_key('reference_snapshot', 'workObject_id')
db.delete_index('reference_snapshot', ['workObject_id'])
db.rename_column('reference_snapshot', 'workObject_id', 'asset_id')
db.alter_column('reference_snapshot', 'asset_id',
                self.gf('django.db.models.fields.related.ForeignKey')(null=True, to=orm['assets.Asset'])

但我收到的错误如下:

DatabaseError: (1091, "Can't DROP 'reference_snapshot_6232368c; check that column/key exists")

实际上,我使用生产服务器(CentOS 6.5)中的转储为我的开发数据库(Windows 7工作站)提供了支持。我看到对索引名称生成(db.create_index_name)的调用在不同平台上没有返回相同的值。

>>> # On WINDOWS
>>> db.create_index_name('reference_snapshot',['workObject_id'])
'reference_snapshot_6232368c'

>>> # On Linux
>>> db.create_index_name('reference_snapshot',['workObject_id'])
'reference_snapshot_9dcdc974'

经过调查,我看到南方应该生成我的索引名称,如下所示:

index_name = '%s_%x' % (table_name, abs(hash((column_name,))) % 2**32)

修改

执行此类代码段会在两个平台上产生相同的值。但是,对create_index_name的调用却没有。悖论。也许南方没有使用我认为的代码。

对该代码片段的调用实际上会产生不同的结果。

>>> # On windows
>>> hash((column_name,))
1965709063

>>> # On Linux
>>> hash((column_name,))
-791966850447943929

如果在没有调用% 2**32的情况下进行32位截断/填充(abs())部分,则结果将是相同的。

我从中得出结论,散列是基于Windows的32位(即使我使用的是64位python),还有基于linux的64位。

结束编辑

所以我陷入困境,因为我无法在Windows上使用生产转储来测试我的迁移。 有任何想法吗?也许在我的开发工作站上修补一些东西可以解决问题。

由于

1 个答案:

答案 0 :(得分:0)

太糟糕了。我们无法帮助但却遭受哈希实现的差异。 但是我刚才读到,因为Python3在hash()中的随机化,索引名称计算现在(从django 1.5开始)使用md5。 http://south.aeracode.org/ticket/1222