2016-07-12 4 views
0

Я пытаюсь создать класс для базы данных с использованием peewee в python. Это приводит к вложенным классам из-за использования peewee класса с именем meta в моделях. Мой вопрос: как определить базу данных (= db) в классе Meta? Может быть, лучший способ?Класс в классе в классе в python, как обмениваться информацией

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) 

Я обнаружил, что определение классов в __init__ функции моих основных класса работ. Но это, вероятно, не самый предпочтительный подход.

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) 
+3

Лучший способ? Да, не используйте вложенные классы. –

+1

Согласен, это не похоже на хороший подход. Есть ли у вас какие-либо намеки на то, как избежать этого в моем примере? –

ответ

2

Вместо классов гнездования попробуйте наследование. This post имеет довольно приличную информацию о том, как использовать наследование и метаклассы в Python.

Глядя на пример быстрого запуска для peewee, делает что-то вроде этой работы для вас?

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()] 

бездельничать с __init__ методом модели, чтобы увидеть, если вы можете передать экземпляр базы данных при инициализации.

Я останусь далеко вдали от определения класса внутри метода.

Надеюсь, это поможет!

+1

Благодарим вас за помощь и ссылку на сообщение о наследовании. Хорошее чтение. –

+0

Я получаю следующую ошибку при запуске этого кода: 'NameError: name 'Meta' не определен' - он не должен быть рабочим примером? – RandomDude

0

Я закончил с использованием this approach из документации peewee. Он работает, и я избегаю вложенных классов:

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') 
+0

Я не был уверен, как вы относились к глобальной переменной. Рад, что вы нашли решение, которое работает на вас! – pat