Opened 6 years ago
Last modified 18 months ago
#27813 new Bug
BinaryField type inconsistent between sqlite3 (bytes) and postgresql (memoryview)
Reported by: | Antonio Terceiro | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Egor R | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have an application that has the following model:
class Attachment(models.Model): # ... data = models.BinaryField(default=None)
under sqlite3:
In [1]: Attachment.objects.last().data Out[1]: b'Mon Feb 6 16:53:37 UTC 2017\n'
under postgresql:
In [1]: Attachment.objects.last().data Out[1]: <memory at 0x7f1ae8e93108>
i.e. under sqlite the BinaryField values comes as bytes(), and under postgresql it comes as memoryview()
Change History (9)
comment:1 Changed 6 years ago by
comment:2 Changed 6 years ago by
I noticed this because I had a test that checked the value of the data
field after a given operation, and since I was initially developing against sqlite, I compared the value against a bytes()
literal b'...'
. to make the test pass against postgresql as well, I had to cast the value in the database to bytes()
before the comparison.
I would expect to always get the same type, either bytes
or memoryview
. on the other hand, everything else other than that one test just worked. the view that allows for that data to be downloaded worked just fine, because bytes
and memoryview
have a similar enough interface, so maybe this should be just clearly documented.
comment:3 Changed 6 years ago by
Summary: | BinaryField is inconsistent between sqlite3 and postgresql → BinaryField type inconsistent between sqlite3 (bytes) and postgresql (memoryview) |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Cleanup/optimization |
Django's test suite is also casting to bytes for comparison. Accepting for further investigation.
comment:4 Changed 5 years ago by
The same applies to Oracle backend which also returns bytes. One of the reasons we use Django in current project is that we can run it on Oracle (as needed due to historical reasons) but hopefully convert it to PostgreSQL one day. Subtle differences like this make it more complicated. What is the reason to return different data type from PostgreSQL backend?
comment:5 Changed 5 years ago by
My guess is that's how the database or database driver (psycopg2) works.
comment:6 Changed 4 years ago by
I am hit by this as well. Returning HttpResponse(mymodel.mybinaryfield)
returns a literal <memory object at 0xdeadbeef>
string instead of the data on Postgres.
comment:7 Changed 2 years ago by
When using BinaryField as a primary key, it leads to a bug.
For example deleting such a table raises a
TypeError: '<' not supported between instances of 'memoryview' and 'memoryview'
Besides, the resulting type should be consistent, independent on the underlying database.
comment:8 Changed 2 years ago by
Type: | Cleanup/optimization → Bug |
---|---|
Version: | 1.10 → 3.1 |
comment:9 Changed 18 months ago by
Cc: | Egor R added |
---|
I can confirm the difference, however, I can't say if a change should be made. Do you have a suggestion about what to do?