Add Forecast.actual
column
This commit is contained in:
parent
6429165aaf
commit
a5b590b24c
3 changed files with 58 additions and 0 deletions
|
@ -0,0 +1,41 @@
|
||||||
|
"""Store actuals with forecast.
|
||||||
|
|
||||||
|
Revision: #c2af85bada01 at 2021-01-29 11:13:15
|
||||||
|
Revises: #e86290e7305e
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
from urban_meal_delivery import configuration
|
||||||
|
|
||||||
|
|
||||||
|
revision = 'c2af85bada01'
|
||||||
|
down_revision = 'e86290e7305e'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
config = configuration.make_config('testing' if os.getenv('TESTING') else 'production')
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
"""Upgrade to revision c2af85bada01."""
|
||||||
|
op.add_column(
|
||||||
|
'forecasts',
|
||||||
|
sa.Column('actual', sa.SmallInteger(), nullable=False),
|
||||||
|
schema=config.CLEAN_SCHEMA,
|
||||||
|
)
|
||||||
|
op.create_check_constraint(
|
||||||
|
op.f('ck_forecasts_on_actuals_must_be_non_negative'),
|
||||||
|
'forecasts',
|
||||||
|
'actual >= 0',
|
||||||
|
schema=config.CLEAN_SCHEMA,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
"""Downgrade to revision e86290e7305e."""
|
||||||
|
op.drop_column('forecasts', 'actual', schema=config.CLEAN_SCHEMA)
|
|
@ -22,6 +22,10 @@ class Forecast(meta.Base):
|
||||||
time_step = sa.Column(sa.SmallInteger, nullable=False)
|
time_step = sa.Column(sa.SmallInteger, nullable=False)
|
||||||
training_horizon = sa.Column(sa.SmallInteger, nullable=False)
|
training_horizon = sa.Column(sa.SmallInteger, nullable=False)
|
||||||
model = sa.Column(sa.Unicode(length=20), nullable=False)
|
model = sa.Column(sa.Unicode(length=20), nullable=False)
|
||||||
|
# We also store the actual order counts for convenient retrieval.
|
||||||
|
# A `UniqueConstraint` below ensures that redundant values that
|
||||||
|
# are to be expected are consistend across rows.
|
||||||
|
actual = sa.Column(sa.SmallInteger, nullable=False)
|
||||||
# Raw `.prediction`s are stored as `float`s (possibly negative).
|
# Raw `.prediction`s are stored as `float`s (possibly negative).
|
||||||
# The rounding is then done on the fly if required.
|
# The rounding is then done on the fly if required.
|
||||||
prediction = sa.Column(postgresql.DOUBLE_PRECISION, nullable=False)
|
prediction = sa.Column(postgresql.DOUBLE_PRECISION, nullable=False)
|
||||||
|
@ -62,6 +66,7 @@ class Forecast(meta.Base):
|
||||||
sa.CheckConstraint(
|
sa.CheckConstraint(
|
||||||
'training_horizon > 0', name='training_horizon_must_be_positive',
|
'training_horizon > 0', name='training_horizon_must_be_positive',
|
||||||
),
|
),
|
||||||
|
sa.CheckConstraint('actual >= 0', name='actuals_must_be_non_negative'),
|
||||||
sa.CheckConstraint(
|
sa.CheckConstraint(
|
||||||
"""
|
"""
|
||||||
NOT (
|
NOT (
|
||||||
|
|
|
@ -18,6 +18,7 @@ def forecast(pixel):
|
||||||
time_step=60,
|
time_step=60,
|
||||||
training_horizon=8,
|
training_horizon=8,
|
||||||
model='hets',
|
model='hets',
|
||||||
|
actual=12,
|
||||||
prediction=12.3,
|
prediction=12.3,
|
||||||
low80=1.23,
|
low80=1.23,
|
||||||
high80=123.4,
|
high80=123.4,
|
||||||
|
@ -131,6 +132,16 @@ class TestConstraints:
|
||||||
):
|
):
|
||||||
db_session.commit()
|
db_session.commit()
|
||||||
|
|
||||||
|
def test_non_negative_actuals(self, db_session, forecast):
|
||||||
|
"""Insert an instance with invalid data."""
|
||||||
|
forecast.actual = -1
|
||||||
|
db_session.add(forecast)
|
||||||
|
|
||||||
|
with pytest.raises(
|
||||||
|
sa_exc.IntegrityError, match='actuals_must_be_non_negative',
|
||||||
|
):
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
def test_set_prediction_without_ci(self, db_session, forecast):
|
def test_set_prediction_without_ci(self, db_session, forecast):
|
||||||
"""Sanity check to see that the check constraint ...
|
"""Sanity check to see that the check constraint ...
|
||||||
|
|
||||||
|
@ -388,6 +399,7 @@ class TestConstraints:
|
||||||
time_step=forecast.time_step,
|
time_step=forecast.time_step,
|
||||||
training_horizon=forecast.training_horizon,
|
training_horizon=forecast.training_horizon,
|
||||||
model=forecast.model,
|
model=forecast.model,
|
||||||
|
actual=forecast.actual,
|
||||||
prediction=2,
|
prediction=2,
|
||||||
low80=1,
|
low80=1,
|
||||||
high80=3,
|
high80=3,
|
||||||
|
|
Loading…
Reference in a new issue