2016-07-24 40 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