Opened 10 years ago

Last modified 8 years ago

#23222 closed Bug

Empty BinaryField != b'' in Python 2/SQLite — at Initial Version

Reported by: wkschwartz@… Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: py2
Cc: cmawebsite@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Problem

In Python 2, at least under SQLite, the initial value for an empty binary field behaves inconsistently. The ORM thinks it's an empty bytes: b''. The database connection manager thinks it's a buffer. Now, the buffer evaluates to False and has zero length. So it'll mostly work. But not always -- and most importantly to me, not in my unit tests!

See http://stackoverflow.com/q/12625557/1286628

Note this was not a problem under Python 3.4.

Steps to Reproduce

Using Python 2.7.8, SQLite, and either Django 1.7rc2 or Django @ edcc75e5ac5b9dc2f174580e7adacd3be586f8bd (HEAD at the time of this writing; the error exists in both places)

  1. Make a new project and a new app and add the app to settings.py
  2. Fill in app/models.py as follows
from django.db import models                                                                                                         
class BinModel(models.Model):                                                                                                        
    data = models.BinaryField()                                                                                                      
  1. Run from the command line:
(venv) $ ./manage.py makemigrations app ./manage.py migrate && ./manage.py shell
  1. Run from the resulting Python shell
>>> from app import models; m = models.BinModel(); m.save(); n = models.BinModel.objects.get()
>>> m.data
''
>>> m.data == b''
True
>>> n.data
<read-write buffer ptr 0x10eaa62b0, size 0 at 0x10eaa6270>
>>> n.data == b''
False
>>> bool(n.data)
False
>>> len(n.data)
0
>>> bytes(n.data)
''

Note that the same problem persisted when I had a default value for the field. There was no problem under Python 3.4.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top