Set statistics columns to double precision (#55053)

pull/55139/head
Erik Montnemery 2021-08-24 11:18:59 +02:00 committed by GitHub
parent 96056f3fce
commit 0624859bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 8 deletions

View File

@ -351,7 +351,7 @@ def _drop_foreign_key_constraints(connection, engine, table, columns):
)
def _apply_update(engine, session, new_version, old_version):
def _apply_update(engine, session, new_version, old_version): # noqa: C901
"""Perform operations to bring schema up to date."""
connection = session.connection()
if new_version == 1:
@ -486,6 +486,21 @@ def _apply_update(engine, session, new_version, old_version):
start = now.replace(minute=0, second=0, microsecond=0)
start = start - timedelta(hours=1)
session.add(StatisticsRuns(start=start))
elif new_version == 20:
# This changed the precision of statistics from float to double
if engine.dialect.name in ["mysql", "oracle", "postgresql"]:
_modify_columns(
connection,
engine,
"statistics",
[
"mean DOUBLE PRECISION",
"min DOUBLE PRECISION",
"max DOUBLE PRECISION",
"state DOUBLE PRECISION",
"sum DOUBLE PRECISION",
],
)
else:
raise ValueError(f"No schema migration defined for version {new_version}")

View File

@ -19,7 +19,7 @@ from sqlalchemy import (
Text,
distinct,
)
from sqlalchemy.dialects import mysql
from sqlalchemy.dialects import mysql, oracle, postgresql
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.orm.session import Session
@ -39,7 +39,7 @@ import homeassistant.util.dt as dt_util
# pylint: disable=invalid-name
Base = declarative_base()
SCHEMA_VERSION = 19
SCHEMA_VERSION = 20
_LOGGER = logging.getLogger(__name__)
@ -66,6 +66,12 @@ ALL_TABLES = [
DATETIME_TYPE = DateTime(timezone=True).with_variant(
mysql.DATETIME(timezone=True, fsp=6), "mysql"
)
DOUBLE_TYPE = (
Float()
.with_variant(mysql.DOUBLE(asdecimal=False), "mysql")
.with_variant(oracle.DOUBLE_PRECISION(), "oracle")
.with_variant(postgresql.DOUBLE_PRECISION, "postgresql")
)
class Events(Base): # type: ignore
@ -240,11 +246,11 @@ class Statistics(Base): # type: ignore
index=True,
)
start = Column(DATETIME_TYPE, index=True)
mean = Column(Float())
min = Column(Float())
max = Column(Float())
state = Column(Float())
sum = Column(Float())
mean = Column(DOUBLE_TYPE)
min = Column(DOUBLE_TYPE)
max = Column(DOUBLE_TYPE)
state = Column(DOUBLE_TYPE)
sum = Column(DOUBLE_TYPE)
@staticmethod
def from_stats(metadata_id: str, start: datetime, stats: StatisticData):

View File

@ -293,10 +293,21 @@ def compile_statistics(
reset = False
if old_state is None:
reset = True
_LOGGER.info(
"Compiling initial sum statistics for %s, zero point set to %s",
entity_id,
fstate,
)
elif state_class == STATE_CLASS_TOTAL_INCREASING and (
old_state is None or (new_state is not None and fstate < new_state)
):
reset = True
_LOGGER.info(
"Detected new cycle for %s, zero point set to %s (old zero point %s)",
entity_id,
fstate,
new_state,
)
if reset:
# The sensor has been reset, update the sum