0

I am trying to create a class for a database using peewee in python. This results in nested classes due to peewee's use of a class named meta in the models. My question is, how do I define the database (=db) within the class Meta? Is there perhaps a better way?

import peewee as pe

    class DataBase():
        class SensorType(pe.Model):
            name = pe.CharField(max_length=255, unique=True)

            class Meta:
                database = db

    def ___init___(self,filename='sensors.db'):
        db = pe.SqliteDatabase(filename)
        db.connect()
        db.create_tables([self.SensorType],safe=True)

    def add_sensor(self,typeName):
        type, created = self.SensorType.get_or_create(name=typeName)
        return type, created

    def get_sensors(self):
        return self.SensorType.select().order_by(self.SensorType.name)


if __name__ == '__main__':

    myDb = DataBase()
    myDb.add_sensor('Test')

    for type in myDb.get_sensors():     
        print(type.name) 

I found that defining the classes within the __init__ function of my main class works. But it is probably not the preferred approach.

import peewee as pe

class DataBase():
    def __init__(self,filename='sensors.db'):        
       db = pe.SqliteDatabase(filename)
       db.connect()

        class SensorType(pe.Model):
           typename = pe.CharField(max_length=255, unique=True)
           class Meta:
              database = db             

       self.SensorType = SensorType          
       db.create_tables([self.SensorType],safe=True)


    def add_sensor_type(self,typeName):
       type, created = self.SensorType.get_or_create(typename=typeName)
       return type, created

    def get_sensor_types(self):
       return self.SensorType.select()

if __name__ == '__main__':

    myDb = DataBase()
    myDb.add_sensor_type('Test')

    for type in myDb.get_sensor_types():     
        print(type.id, type.typename)
pat
  • 69
  • 2
  • 10

2 Answers2

2

Instead of nesting classes, try inheritance. This post has some fairly decent information on how to use inheritance and metaclasses in Python.

Looking at the quickstart example for peewee, does something like this work for you?

import peewee

class BaseModel(peewee.Model):            
    def __init__(self, db):
        super(BaseModel, self).__init__()
        Meta.database = db

    class Meta:
        database = None

class SensorType(BaseModel):
    def __init__(self, db):
        super(SensorType, self).__init__(db)

    name = peewee.CharField(max_length=255, unique=True)

class DataBase():
    def __init__(self, filename='sensors.db'):
        self.db = peewee.SqliteDatabase(filename)
        self.sensor_type = SensorType(self.db)
        self.db.connect()
        self.db.create_tables([self.sensor_type], safe=True)

    def add_sensor(self, typeName):
        type, created = self.sensor_type.get_or_create(name=typeName)
        return type, created

    def get_sensors(self):
        return self.sensor_type.select().order_by(self.sensor_type.name)

if __name__ == '__main__':
    db = DataBase()

    db.add_sensor('Test')
    [print(type.name) for type in db.get_sensors()]

Mess around with the model's __init__ method to see if you can pass a database instance upon initialization.

I would stay far away from defining a class inside a method.

I hope this helps!

Community
  • 1
  • 1
pat
  • 69
  • 2
  • 10
0

I ended up using this approach from peewee documentation. It works and I avoid the nested classes:

import peewee as pe
database = pe.SqliteDatabase(None)

class BaseModel(pe.Model):
    class Meta:
        database = database

class SensorType(BaseModel):
    name = pe.CharField(max_length=255, unique=True)

class DataBase():
    def __init__(self, filename='sensors.db'):
        database.init(filename)
        self.sensor_type = SensorType()
        database.connect()
        database.create_tables([self.sensor_type], safe=True)        

if __name__ == '__main__':
    db = DataBase('test.db')
  • I was not sure how you felt about a global variable. Glad you found a solution that works for you! – pat Jul 13 '16 at 13:10