我正在研究一个带有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上使用生产转储来测试我的迁移。 有任何想法吗?也许在我的开发工作站上修补一些东西可以解决问题。
由于
答案 0 :(得分:0)
太糟糕了。我们无法帮助但却遭受哈希实现的差异。 但是我刚才读到,因为Python3在hash()中的随机化,索引名称计算现在(从django 1.5开始)使用md5。 http://south.aeracode.org/ticket/1222