Ticket #578 (closed defect: fixed)
Boolean default values are not set correctly when adding new columns with sqlite
| Reported by: | luper.rouch@… | Owned by: | andrew |
|---|---|---|---|
| Priority: | minor | Milestone: | 1.0 |
| Component: | databaseapi | Version: | 0.7.2 |
| Keywords: | sqlite boolean | Cc: | luper.rouch@… |
Description
If you add a new BooleanField to a model, with default=True in a SQLite database, the column will be filled with 'True' strings after migration, and that won't be interpreted as True booleans in Django.
This is because SQLite doesn't have a boolean type, and Django expects booleans to be stored as '1' or '0' in SQLite databases. The problem is specific to SQLite, other database backends recognize "DEFAULT True" properly as a boolean value.
To fix this we need some sort of database-specific mechanism to transform Python values to their SQL representation. Attached is a patch with a suggestion of API to do this properly, and the fix for this particular SQLite problem.
Note: the patch also uses django's Field.get_db_prep_save() method to transform the default values to their database representation, which I believe is the correct way to process values before passing them to the database layer.
Attachments
Change History
comment:1 Changed 3 years ago by andrew
- Status changed from new to accepted
- Milestone changed from 0.7.3 to 1.0
That's quite a change to the module, but I see exactly where you're coming from. I'll review it over in a bit - hopefully it will be fine.
comment:4 Changed 20 months ago by klaas@…
Note:
This bug equally applies to default=False, i.e. "False" string values are inserted into the database in that case.
comment:6 Changed 18 months ago by tony@…
Oops, didn't mean to post as anonymous. Here's what I saw:
>>> Company.objects.filter(approved=False).count() 2 >>> Company.objects.filter(approved=True).count() 1 >>> Company.objects.all().count() 43 >>> Company.objects.filter(approved__isnull=True).count() 0
In the actual sqlite database, the majority of the rows had approved="False", but there were two where it was 0 and one where it was 1.
comment:8 Changed 14 months ago by andrew
- Status changed from accepted to closed
- Resolution set to fixed
Fixed in [916f74766c26].
comment:9 Changed 7 months ago by michel@…
Can this be reopened?
In version 0.7.6 I still ran into this problem.
The migration of a field with percentage in it (in my case a dateformat '%B %Y').
Adding this field went OK in migrations.
The problem started with any migration in this table after this migrations.
Recreating the table will fail, see: http://stackoverflow.com/questions/12442768
or this stacktrace:
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/sqlite3.py", line 31, in add_column
field.column: self._column_sql_for_create(table_name, name, field, False),
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/generic.py", line 44, in _cache_clear
return func(self, table, *args, **opts)
File "/media/storage/django/sites/palmrif/eggs/South-0.7.6-py2.7.egg/south/db/sqlite3.py", line 103, in _remake_table
", ".join(["%s %s" % (self.quote_name(cname), ctype) for cname, ctype in definitions.items()]),
comment:10 Changed 7 months ago by Michel van Leeuwen <michel@…>
- Status changed from closed to reopened
- Resolution fixed deleted
comment:11 Changed 7 months ago by Michel van Leeuwen <michel@…>
Oops, sorry wrong ticket.
I was struggling with 2 problems:
default boolean value and the percentage in deafult value.
I found out it was the percentage value
Now I reopened the wrong ticket.....
comment:12 Changed 7 months ago by andrew
- Status changed from reopened to closed
- Resolution set to fixed
