This bug only appears when using SQLAlchemy  with C extensions compiled and 
a database that does not have a native BOOLEAN type.

If you have a boolean SQLAlchemy column with a MySQL database, when 
SQLAlchemy sets the value of this column for a particular row, it can be 
any tinyint value. This function (bolean_to_int) is run to convert the 
supplied value to an integer for storage: 
https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/processors.py#L52

When the record is retrieved, and SQLAlchemy is using C extensions, this 
function is used to convert the stored integer to a boolean value. In this 
case, the function explicitly throws an error when the value is anything 
other than None, 0, or 1: 
https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/cextension/processors.c#L23

I think it's reasonable for a developer using SQLAlchemy to run a web 
service that takes user input and assigns it to a model's boolean column. 
If they do not explicitly convert it to a boolean beforehand, assuming that 
SQLAlchemy will do the necessary conversion, the user may set the boolean 
column to a value such as "3." Then, any time that record is retrieved 
SQLAlchemy will throw an error and the request will 500.

I think it's a reasonable mistake for the developer to make because the 
SQLAlchemy docs claim that a constraint is created by default which limits 
the value stored in the database to 1 or 0: 
http://docs.sqlalchemy.org/en/latest/core/type_basics.html?highlight=boolean#sqlalchemy.types.Boolean.params.create_constraint

It looks like this bug has been seen by others, but the underlying behavior 
of SQLAlchemy was never addressed: 
https://groups.google.com/forum/#!searchin/sqlalchemy/boolean/sqlalchemy/n5UadJrTjfA/SBspf9C_WJYJ

In my opinion, either the code to retrieve a boolean from an int in the 
database should be modified to work for any value that SQLAlchemy supports 
inserting into the column, or the docs should be updated to explain that 
retrieval will fail in this specific case.

It's worth noting that if you do not use C extensions, the code works fine 
because in Python any non-zero value is implicitly True.

- Robert

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to