2017-05-30 6 views
1

このアプリケーションには、データベースに保存されている人のリストがリアルタイムで計算され、この値は決してデータベースに格納されません。また、データベース、フィールドなどのデータベースフィールドで動作するクラスを1つ使用したいとします。sqlalchemyマッピングクラスの非データベース属性への追加

sqlalchemyでは可能ですか?今私は継承を使用していますMan - > 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

私の見解では、2つの異なるクラスが必要です。 あなたのコードのロジック用とDBとの通信用のもの。

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) 

あなたはManModelオブジェクトをDBに問い合わせを行い、プロバイダを持っている必要があり、その後、マンオブジェクトに結果をマップし、呼び出し元にマップされたデータを返します。 アプリケーションはオブジェクトのみを使用し、プロバイダはマッピングを行います。 次のようなもの:

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

名前、評価の2つの列でテーブルを印刷するにはどうすればよいですか?この仕事をするには複雑すぎるだろう。 – Serge

+0

私のサンプルでは、​​Manオブジェクトには両方の値(名前と評価)が含まれています。だから私はちょうど私が作成したdisplay_manメソッドを呼び出すことができます。評価がどのように計算されるかによっても異なります。 – M07

+0

私はあまりにも変に思えるかもしれませんが、これは私が使いたいコードではありません。しかし、非常に近い) – Serge

1

DBのデータを使用して評価を計算する場合は、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

関連する問題