django-cryptography icon indicating copy to clipboard operation
django-cryptography copied to clipboard

Using unique=True on MySQL fails due to missing "key length"

Open flyte opened this issue 4 years ago • 1 comments

When creating (in a migration) an encrypted field that has unique=True, the MySQL backend gives the following error:

MySQLdb._exceptions.OperationalError: (1170, "BLOB/TEXT column 'email_new' used in key specification without a key length")

This SO post explains the reason behind the error: https://stackoverflow.com/a/1827099/1791183

1, Is this something that django-cryptography can fix? 2. Will unique=True even work on an encrypted field? 3. Is there a workaround?

flyte avatar May 12 '20 14:05 flyte

To question 2 I say no; it might work on some databases, but generally no.

To question3, yes. The workaround is a little ugly, but it works. Decrypt each row and compare it to new candidate row and see if there is a collision:

for row in EncryptedModel.objects.all():
  if row.unique_attribute == new_unique_attribute:
    raise Exception("bruh... are you fr advocating for a full record search?? yes, but only because there is no alternative")

thismatters avatar Apr 12 '21 20:04 thismatters