Django BinaryField retrieved as memory position?

2024/10/8 14:37:15

I've written a short unit test with the following code:

my_object = MyObject()
my_object.data = b'12345'my_object.save()
saved_object = MyObject.objects.first()assert saved_object.data == my_object.data

where MyObject is defined as:

class MyObject(models.Model):data = models.BinaryField(default=None)

I would expect the assert to pass, as I'm just saving some byte data and then retrieving it. However, I end up with:

AssertionError: assert <memory at 0x10e2abc48> == b'12345'

I'm guessing that it has to do with directly saving the byte string to the binary field. On the other hand, it seems strange that the save succeeds at all then. And I'm having a bit of difficultly finding some good example uses of Django's BinaryField. Can anyone explain to me what's happening here or what I'm doing wrong? Thank you much.

Answer

Django normalizes the content of the BinaryField to a buffer. In Python2 to buffer and memoryview in Python3 to be specific.

You can see that in source code:

  • to_python source
  • six.memoryview source

In Python2 buffer does not implement comparison logic which is why your assertion fails:

Python 2.7.11
>>> m = buffer(b'hello')
>>> m == b'hello'
False
>>> bytes(m) == b'hello'
True

However it does implement other operations such as slicing and length:

>>> len(m)
5
>>> m[1:]
'ello'

In Python 3 the story is much better since it implements all expected operations:

Python 3.5.1
>>> m = memoryview(b'hello')
>>> m
<memory at 0x109e8b108>
>>> bytes(m)
b'hello'
>>> m == b'hello'
True
>>> bytes(m) == b'hello'
True
>>> len(m)
5
>>> m[1:]
<memory at 0x109e8b1c8>

Im not sure the reason why Django does that however my guess would be for efficiency. Buffers are much more efficient at handling memory. For example when you slice, it can reuse the same memory vs allocating more memory.

https://en.xdnf.cn/q/70109.html

Related Q&A

difflib.SequenceMatcher isjunk argument not considered?

In the python difflib library, is the SequenceMatcher class behaving unexpectedly, or am I misreading what the supposed behavior is?Why does the isjunk argument seem to not make any difference in this…

PyCharm Code Folding/Outlining Generates Wrong Boundaries

Im having a very frustrating issue with PyCharm in that it does not want to properly outline the code so that blocks fold correctly. Ive looked all over the place and couldnt find any help with this pa…

How to clear the conda environment variables?

While I was setting an environment variable on a conda base env, I made an error in the path that was supposed to be assigned to the variable. I was trying to set the $PYSPARK_PYTHON env variable on th…

Create duplicates in the list

I havelist = [a, b, c, d]andnumbers = [2, 4, 3, 1]I want to get a list of the type of:new_list = [a, a, b, b, b, b, c, c, c, d]This is what I have so far:new_list=[] for i in numbers: for x in list: f…

cxfreeze aiohttp cannot import compat

Im trying to use cx_freeze to build a binary dist for an web application written in Python 3 using the aiohttp package.Basically I did:cxfreeze server.pyand got a dist outputBut when running the ./serv…

Python open() requires full path [duplicate]

This question already has answers here:open() gives FileNotFoundError / IOError: [Errno 2] No such file or directory(11 answers)Closed 9 months ago.I am writing a script to read a csv file. The csv fil…

Pandas to parquet file

I am trying to save a pandas object to parquet with the following code: LABL = datetime.now().strftime("%Y%m%d_%H%M%S") df.to_parquet("/data/TargetData_Raw_{}.parquet".format(LABL))…

Wildcard in dictionary key

Suppose I have a dictionary:rank_dict = {V*: 1, A*: 2, V: 3,A: 4}As you can see, I have added a * to the end of one V. Whereas a 3 may be the value for just V, I want another key for V1, V2, V2234432, …

How to read emails from gmail?

I am trying to connect my gmail to python, but show me this error: I already checked my password, any idea what can be? b[AUTHENTICATIONFAILED] Invalid credentials (Failure) Traceback (most recent cal…

Python multiprocessing returning AttributeError when following documentation code [duplicate]

This question already has answers here:python multiprocessing in Jupyter on Windows: AttributeError: Cant get attribute "abc"(4 answers)Closed 4 years ago.I decided to try and get into the mu…