Django中区分大小写的搜索,但在Mysql中忽略大小写

7

我在Django模型中有一个用于存储唯一(哈希)值的字段。结果发现数据库(MySQL/inno)不对此类型(VARCHAR)进行区分大小写的搜索,即使我明确告诉Django要进行区分大小写的搜索Document.objects.get(hash__exact="abcd123")。因此,"abcd123"和"ABcd123"都会被返回,而这不是我想要的。

class document(models.Model):
   filename    = models.CharField(max_length=120)
   hash        = models.CharField(max_length=33 )

我可以将“哈希字段”更改为BinaryField,这样在数据库中它就变成了LONGBLOB,并且确实进行了区分大小写的搜索(并且有效)。但是,这对我来说似乎不太高效。 在Django中是否有更好的方法来做到这一点,例如添加“utf8 COLLATE”?或者在这种情况下应该使用什么正确的字段类型? (是的,我知道我可以改用PostgreSQL..)

2个回答

4

MySQL 的默认字符集排序规则是 latin1_swedish_ci,大小写不敏感。不确定为什么会这样。但你应该像这样创建你的数据库:

CREATE DATABASE database_name CHARACTER SET utf8;

我已经更改了数据库,但我希望这可以在Django内完成。但这也可以。 - Alex
你真的应该始终使用utf8。如果不这样做,你肯定会遇到问题。 - dan-klasson

2
正如@dan-klasson所提到的,默认的非二进制字符串比较默认情况下是不区分大小写的;请注意latin1_swedish_ci末尾的_ci,它代表不区分大小写。
你可以像Dan提到的那样,使用区分大小写的排序规则和字符集创建数据库。
你可能也想知道,你总是可以为单个表甚至仅设置单个列使用不同的排序规则(达到相同的结果)。并且你也可以在创建后更改这些排序规则,例如每个表:
ALTER TABLE documents__document CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

此外,如果您不想更改数据库/表字符集/排序规则,Django允许使用原始方法运行自定义查询。因此,您可以通过使用以下类似内容来解决此问题,但我自己没有测试过:(使用原始SQL查询)
Document.objects.raw("SELECT * FROM documents__document LIKE '%s' COLLATE latin1_bin", ['abcd123'])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接