Search code examples
pythonormpeewee

peewee refers to a base class table that does not exist


The following set-up illustrates my problem:

from peewee import (Model, 
                    SqliteDatabase)
from peewee import (CharField,
                    ForeignKeyField,
                    IntegerField)

from playhouse.shortcuts import model_to_dict

database = SqliteDatabase(':memory:')

class BaseModel(Model):

    class Meta:
        database = database

class Description(BaseModel):
    i_am = CharField(
        db_column='I_AM'
        )
    class Meta:
        db_table = 'DESCRIPTION'

# This is not a table, just a convenient class to inherit from.
class ValueBase(BaseModel):
    value = IntegerField(
        db_column='VALUE'
        )
    description = ForeignKeyField(
        db_column='I_AM_ID',
        rel_model=Description,
        to_field='id'
        )

class SpecificValue(ValueBase):

    class Meta:
        db_table = 'SPECIFIC_VALUE'

if __name__ == '__main__':

    models = [Description, SpecificValue]
    database.create_tables(models)

    description = Description(
        i_am = 'prime'
        )
    description.save()

    specific = SpecificValue(
        value=7,
        description=description
        )
    specific.save()

    ### This works 
    print model_to_dict(
        specific
        )
    ### This does NOT work
    print model_to_dict(
        specific,
        backrefs=True
        )

The problem is that when I use model_to_dict and ask for back references, then the function thinks specific is in a table valuebase and not in a table called SPECIFIC_VALUE. Does anyone know how to do this sort of inheritance and correctly set table names?

EDIT

The traceback is as follows:

Traceback (most recent call last):
  File "/home/lafras/Projects/Cloud/eg.py", line 61, in <module>
    backrefs=True
  File "build/bdist.linux-x86_64/egg/playhouse/shortcuts.py", line 96, in model_to_dict
  File "build/bdist.linux-x86_64/egg/playhouse/shortcuts.py", line 117, in model_to_dict
  File "build/bdist.linux-x86_64/egg/peewee.py", line 2794, in __iter__
  File "build/bdist.linux-x86_64/egg/peewee.py", line 2787, in execute
  File "build/bdist.linux-x86_64/egg/peewee.py", line 2470, in _execute
  File "build/bdist.linux-x86_64/egg/peewee.py", line 3199, in execute_sql
  File "build/bdist.linux-x86_64/egg/peewee.py", line 3048, in __exit__
  File "build/bdist.linux-x86_64/egg/peewee.py", line 3191, in execute_sql
peewee.OperationalError: no such table: valuebase

If SpecificValue inherits directly from BaseModel:

class SpecificValue(BaseModel):
    value = IntegerField(
        db_column='VALUE'
        )
    description = ForeignKeyField(
        db_column='I_AM_ID',
        rel_model=Description,
        to_field='id'
        )

    class Meta:
        db_table = 'SPECIFIC_VALUE'

then the output is as expected:

{'id': 1, 'value': 7, 'description': {'id': 1, 'i_am': 'prime'}}

Solution

  • Can you explain a bit more thoroughly what's not working correctly? I don't see any back-references that would be associated with the SpecificValue table, since there are not other models that have a foreign key to it.

    EDIT:

    OK, so what's happening here is that when you specify backrefs, peewee is trying to go from:

    SpecificValue -> Description -> ValueBase (which has a foreign key to description).

    The fix is to explicitly exclude the backref:

    model_to_dict(specific, backrefs=True, exclude=[Description.valuebase_set])