Hi,

I'm using the Versioned class from the examples, and I noticed that
when I set a Boolean column to None (NULL in the db), the eventual
history row corresponding to that change gets a 0 rather than a NULL.

In the test script below, I create an instance of a versioned class,
with a boolean property initially set to False. I set it to None, and
check that the history table records the old False value, then I set
it to True and check that the history table records the old None
value. The final assertion fails because None was actually inserted as
0. I've tested using 0.8.2 and 0.9.3, against sqlite and mysql, and
get the same results.

I've instrumented the create_version function in history_meta.py, and
as far as I can tell everything looks fine. The boolean column in the
history table is nullable, the bind processor for the column is
boolean_to_int, and calling that function with None returns None as
expected. But the INSERT statement is inserting a 0:

sqlalchemy.engine.base.Engine INSERT INTO sometable_history (id, name,
somebool, version, changed) VALUES (?, ?, ?, ?, ?)
sqlalchemy.engine.base.Engine (1, u'sc1modified', 0, 2, '2014-02-24
11:56:31.730591')

Here's the test script:

from sqlalchemy.ext.declarative import declarative_base
import sqlalchemy as sa
import sqlalchemy.orm as saorm

from history_meta import Versioned, versioned_session

Base = declarative_base()
Session = saorm.sessionmaker()
versioned_session(Session)

class SomeClass(Versioned, Base):
    __tablename__ = 'sometable'
    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String(50))
    somebool = sa.Column(sa.Boolean, default=False)

def test():
    engine = sa.create_engine('sqlite://', echo='debug')
    Base.metadata.create_all(engine)
    session = Session(bind=engine)

    def someboolhistory():
        SomeClassHistory = SomeClass.__history_mapper__.class_
        history = (session.query(SomeClassHistory)
                   .order_by(SomeClassHistory.version)
                   .all())
        return [h.somebool for h in history]

    def checkhistory(expected):
        actual = someboolhistory()
        assert actual == expected, ('%s != %s' % (expected, actual))

    sc = SomeClass(name='sc1', somebool=False)
    session.add(sc)
    session.commit()

    sc.name = 'sc1modified'
    sc.somebool = None
    session.commit()

    checkhistory([False])

    sc.name = 'sc1modified2'
    sc.somebool = True
    session.commit()

    checkhistory([False, None])

if __name__ == '__main__':
    test()


Thanks in advance for any help,

Simon

-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to