2016-07-24 4 views
0

Float型の1時間ごとの列を含むテーブルを作成したいとします。 は、どのように私はこの冗長な構文を取り除くん:Postgresを使用したSqlAlchemyモデルの動的生成フィールド

from app import db 

class HourlySchedule(db.Model): 
    id = db.Column(
     db.Integer, 
     primary_key=True 
    ) 

    h0 = db.Column(db.Float, nullable=True) 
    h1 = db.Column(db.Float, nullable=True) 
    h2 = db.Column(db.Float, nullable=True) 
    h3 = db.Column(db.Float, nullable=True) 
    h4 = db.Column(db.Float, nullable=True) 
    h5 = db.Column(db.Float, nullable=True) 
    h6 = db.Column(db.Float, nullable=True) 
    h7 = db.Column(db.Float, nullable=True) 
    h8 = db.Column(db.Float, nullable=True) 
    h9 = db.Column(db.Float, nullable=True) 
    h10 = db.Column(db.Float, nullable=True) 
    h11 = db.Column(db.Float, nullable=True) 
    h12 = db.Column(db.Float, nullable=True) 
    h13 = db.Column(db.Float, nullable=True) 
    h14 = db.Column(db.Float, nullable=True) 
    h15 = db.Column(db.Float, nullable=True) 
    h16 = db.Column(db.Float, nullable=True) 
    h17 = db.Column(db.Float, nullable=True) 
    h18 = db.Column(db.Float, nullable=True) 
    h19 = db.Column(db.Float, nullable=True) 
    h20 = db.Column(db.Float, nullable=True) 
    h21 = db.Column(db.Float, nullable=True) 
    h22 = db.Column(db.Float, nullable=True) 
    h23 = db.Column(db.Float, nullable=True) 

もう一つの問題は、私は値(例えば0 < =値= 1 <)にチェックを強制しない方法ですか?

妥当性確認として?それでは、どのように私は24フィールドのためにきれいにバリデーションを設定するのですか?

代わりに、SqlAlchemyでチェック制約を追加できますか?

+0

あなたが本当にあなたのテーブルに24列を持つようにしたい場合は、何もありません冗長なアプローチでは間違っています。制限チェックのために[validator](http://docs.sqlalchemy.org/en/rel_0_9/orm/mapped_attributes.html#simple-validators)を記述することができます。 – Selcuk

+0

次に、「動的に生成されたバリデータをSqlAlchemyに登録する」という質問を投稿します。 – Alain1405

答えて

-1

super().__init__(*args, **kwargs)を呼び出す順番で遊ぶ必要があるかもしれませんが、理論的にはうまくいくはずです。検証用として

validatesデコレータの良いところは、それが複数の列名を取るということですので、我々はそうのような動的なフィールドの作成と検証を実現することができます:私は注意したい

from app import db 
from sqlalchemy.orm import validates 


class HourlySchedule(db.Model): 
    id = db.Column(
     db.Integer, 
     primary_key=True 
    ) 

    def __init__(self, *args, **kwargs): 
     self.colstrings = [] 

     for hour in range(0, 24): 
      colstring = "h{}".format(hour) 
      setattr(self, colstring, db.Column(db.Float, nullable=True)) 
      self.colstrings.append(colstring) 

     super().__init__(*args, **kwargs) 

    @validates(*self.colstrings) 
    def validate_hours(self, key, hour): 
     assert 0 < hour < 1 
     return hour 

一つのことしかし、これは実際にはむしろ単純な概念の複雑さを大幅に増加させるということです。モデルの詳細を隠す代わりに、冗長でモデル>テーブルのマッピングを簡単に理解できるので、各列を列挙するか、データをどのように構造化しているかを再考するのがより理にかなっているかもしれません。ここ

0

キーがclassブロックは、コードのわずか1ブロックであることを認識することがあるので、あなたはそこにループを置くことができます。

class HourlySchedule(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 

    for i in range(24): 
     locals()["h{}".format(i)] = db.Column(db.Float) 

    @validates(*("h{}".format(i) for i in range(24))) 
    def _validate(self, k, h): 
     assert 0 <= h <= 1 
     return h 
関連する問題