Modify

Ticket #578 (closed defect: fixed)

Opened 3 years ago

Last modified 7 months ago

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

fix-sqlite-bool-defaults.patch (3.7 KB) - added by Luper Rouch <luper.rouch@…> 3 years ago.

Change History

Changed 3 years ago by Luper Rouch <luper.rouch@…>

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:2 Changed 3 years ago by andrew

  • Cc luper.rouch@… added

comment:3 Changed 2 years ago by christian@…

just ran into this.

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:5 Changed 18 months ago by anonymous

I was just burned by this too.

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:7 Changed 16 months ago by bradley.ayers@…

I just ran into this too.

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
View

Add a comment

Modify Ticket

Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.