tags:

views:

73

answers:

2

In a Django application, I'm trying to access an existing MySQL database created with Hibernate (a Java ORM). I reverse engineered the model using:

$ manage.py inspectdb > models.py

This created a nice models file from the Database and many things were quite fine. But I can't find how to properly access boolean fields, which were mapped by Hibernate as columns of type BIT(1).

The inspectdb script by default creates these fields in the model as TextField and adds a comment saying that it couldn't reliably obtain the field type. I changed these to BooleanField but and opened my model objects using the admin, but it doesn't work (the model objects always fetch a value of true for these fields). Using IntegerField won't work as well (e.g. in the admin these fields show strange non-ascii characters).

Any hints of doing this without changing the database? (I need the existing Hibernate mappings and Java application to still work with the database).


Further info: I left these fields as BooleanField and used the interactive shell to look at the fetched values. They are returned as '\x00' (when Java/Hibernate value is false) and '\x01' (when true), instead of Python boolean values "True" and "False".

>>> u = AppUser.objects.all()[0]
>>> u.account_expired
'\x00'
>>> u.account_enabled
'\x01'

Where the model includes:

class AppUser(models.Model):
    account_expired = models.BooleanField()
    account_enabled = models.BooleanField(blank=True)
    # etc...
+2  A: 

I guess that only way is to subclass, say, BooleanField, and override to_python/get_prep_value functions, so the field works seamlessly with django and your db.

Dmitry Shevchenko
Great, that solved it. Since I am using Django 1.1.1 I had to use get_db_prep_value instead of get_prep_value. See detailed solution below
Carles Barrobés
+3  A: 

This is the detailed solution from Dmitry's suggestion:

My derived field class:

class MySQLBooleanField(models.BooleanField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        if isinstance(value, bool):
            return value
        return bytearray(value)[0]

    def get_db_prep_value(self, value):
        return '\x01' if value else '\x00'

Fields in my model:

account_enabled = MySQLBooleanField()
account_expired = MySQLBooleanField()
Carles Barrobés