2016-07-24 66 views
0

我想創建一個列的浮動類型當天的每個小時列。 如何擺脫這個冗長的語法:動態生成SqlAlchemy模型與Postgres中的字段

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列,有什麼詳細的方法是錯誤的。你可以編寫一個[驗證器](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塊僅僅是一個代碼塊,所以你可以把循環在那裏:

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