2017-05-30 69 views
1

该应用程序具有这样的逻辑:存储在数据库中的人员列表,每个人都具有实时计算的评级,并且该值从不存储在数据库中。我想用一个类来处理dababase字段:名称,年龄等和非数据库字段:评级。添加到sqlalchemy映射类非数据库属性

sqlalchemy有可能吗?现在我正在使用继承人 - > ManMapping:

class Man: 
    rating = None 

    def get_rating(self): 
    return self.rating 

    ... 

class ManMapping(Base, Man): 
    __tablename__ = 'man' 
    id = Column('man_id', Integer, primary_key=True) 
    name = Column(Unicode) 

    ... 

它的作品,但它看起来很可怕。这是正确的方法还是我必须做别的事情?

回答

1

在我看来,你应该有两个区别类。 一个用于代码中的逻辑,另一个用于与您的数据库进行通信。

class Man(object): 
    """This class is for your application""" 
    def __init__(self, name, rating): 
     # If the identifier is only used by the DB it should not be in this class 
     self.name = name 
     self.rating = rating 

class ManModel(Base): 
    """This model is only to communicate with the DB""" 
    __tablename__ = 'man' 
    id = Column('man_id', Integer, primary_key=True) 
    name = Column(Unicode) 

你应该有一个供应商,确实查询DB与ManModel对象,然后地图搜寻结果,对象和你映射的数据返回给调用者。 您的应用程序将只使用Man对象,您的提供者将执行映射。 类似如下:

class DbProvider(object): 
    def get_man(self, id): 
     man_model = session.query(ManModel).filter(ManModel.id == id).one_or_none() 
     return self.man_mapper(man_model) if man_model else None 

    def get_men(self): 
     men_model = session.query(ManModel).all() 
     return [self.man_mapper(man_model) for man_model in men_model] 

    def man_mapper(self, man_model): 
     return Man(man_model.name, self.calculate_rating(man_model)) 

class Test(object): 
     def display_man(self): 
      man = db_provider.get_man(15) 
      if man: 
       print man.name, man.rating 
+0

我需要做什么来打印两列的表:名称,评级?这个任务太复杂了。 – Serge

+0

在我的示例中,Man对象包含两个值(名称和评分)。所以你可以调用我刚刚创建的display_man方法。这也取决于如何计算评分。 – M07

+0

也许我太反复无常了,但这不是我想要使用的代码。但非常接近) – Serge

1

如果您使用数据库中的任何数据来计算评分,我会建议您查看hybrid property。否则,我会添加self.rating到初始并在ManMapping类中有你的函数。例如:

class ManMapping(Base): 
    __tablename__ = 'man' 
    id = Column('man_id', Integer, primary_key=True) 
    name = Column(Unicode) 

    def __init__(self) 
     self.rating = None 

    def get_rating(self): 
     return self.rating 
+0

由于某些原因,使用* init *的情况下不起作用。但是,如果我在名称之后初始化评级,它的工作。也许这是我不知道的方式。不管怎样,谢谢你。 – Serge