mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
Reduce time syscalls needed to insert new statistics (#131984)
This commit is contained in:
parent
47aebabc51
commit
8878d0f0e1
@ -691,12 +691,14 @@ class StatisticsBase:
|
|||||||
duration: timedelta
|
duration: timedelta
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_stats(cls, metadata_id: int, stats: StatisticData) -> Self:
|
def from_stats(
|
||||||
|
cls, metadata_id: int, stats: StatisticData, now_timestamp: float | None = None
|
||||||
|
) -> Self:
|
||||||
"""Create object from a statistics with datetime objects."""
|
"""Create object from a statistics with datetime objects."""
|
||||||
return cls( # type: ignore[call-arg]
|
return cls( # type: ignore[call-arg]
|
||||||
metadata_id=metadata_id,
|
metadata_id=metadata_id,
|
||||||
created=None,
|
created=None,
|
||||||
created_ts=time.time(),
|
created_ts=now_timestamp or time.time(),
|
||||||
start=None,
|
start=None,
|
||||||
start_ts=stats["start"].timestamp(),
|
start_ts=stats["start"].timestamp(),
|
||||||
mean=stats.get("mean"),
|
mean=stats.get("mean"),
|
||||||
@ -709,12 +711,17 @@ class StatisticsBase:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_stats_ts(cls, metadata_id: int, stats: StatisticDataTimestamp) -> Self:
|
def from_stats_ts(
|
||||||
|
cls,
|
||||||
|
metadata_id: int,
|
||||||
|
stats: StatisticDataTimestamp,
|
||||||
|
now_timestamp: float | None = None,
|
||||||
|
) -> Self:
|
||||||
"""Create object from a statistics with timestamps."""
|
"""Create object from a statistics with timestamps."""
|
||||||
return cls( # type: ignore[call-arg]
|
return cls( # type: ignore[call-arg]
|
||||||
metadata_id=metadata_id,
|
metadata_id=metadata_id,
|
||||||
created=None,
|
created=None,
|
||||||
created_ts=time.time(),
|
created_ts=now_timestamp or time.time(),
|
||||||
start=None,
|
start=None,
|
||||||
start_ts=stats["start_ts"],
|
start_ts=stats["start_ts"],
|
||||||
mean=stats.get("mean"),
|
mean=stats.get("mean"),
|
||||||
|
@ -11,6 +11,7 @@ from itertools import chain, groupby
|
|||||||
import logging
|
import logging
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
import re
|
import re
|
||||||
|
from time import time as time_time
|
||||||
from typing import TYPE_CHECKING, Any, Literal, TypedDict, cast
|
from typing import TYPE_CHECKING, Any, Literal, TypedDict, cast
|
||||||
|
|
||||||
from sqlalchemy import Select, and_, bindparam, func, lambda_stmt, select, text
|
from sqlalchemy import Select, and_, bindparam, func, lambda_stmt, select, text
|
||||||
@ -446,8 +447,9 @@ def _compile_hourly_statistics(session: Session, start: datetime) -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Insert compiled hourly statistics in the database
|
# Insert compiled hourly statistics in the database
|
||||||
|
now_timestamp = time_time()
|
||||||
session.add_all(
|
session.add_all(
|
||||||
Statistics.from_stats_ts(metadata_id, summary_item)
|
Statistics.from_stats_ts(metadata_id, summary_item, now_timestamp)
|
||||||
for metadata_id, summary_item in summary.items()
|
for metadata_id, summary_item in summary.items()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -578,6 +580,7 @@ def _compile_statistics(
|
|||||||
|
|
||||||
new_short_term_stats: list[StatisticsBase] = []
|
new_short_term_stats: list[StatisticsBase] = []
|
||||||
updated_metadata_ids: set[int] = set()
|
updated_metadata_ids: set[int] = set()
|
||||||
|
now_timestamp = time_time()
|
||||||
# Insert collected statistics in the database
|
# Insert collected statistics in the database
|
||||||
for stats in platform_stats:
|
for stats in platform_stats:
|
||||||
modified_statistic_id, metadata_id = statistics_meta_manager.update_or_add(
|
modified_statistic_id, metadata_id = statistics_meta_manager.update_or_add(
|
||||||
@ -587,10 +590,7 @@ def _compile_statistics(
|
|||||||
modified_statistic_ids.add(modified_statistic_id)
|
modified_statistic_ids.add(modified_statistic_id)
|
||||||
updated_metadata_ids.add(metadata_id)
|
updated_metadata_ids.add(metadata_id)
|
||||||
if new_stat := _insert_statistics(
|
if new_stat := _insert_statistics(
|
||||||
session,
|
session, StatisticsShortTerm, metadata_id, stats["stat"], now_timestamp
|
||||||
StatisticsShortTerm,
|
|
||||||
metadata_id,
|
|
||||||
stats["stat"],
|
|
||||||
):
|
):
|
||||||
new_short_term_stats.append(new_stat)
|
new_short_term_stats.append(new_stat)
|
||||||
|
|
||||||
@ -666,10 +666,11 @@ def _insert_statistics(
|
|||||||
table: type[StatisticsBase],
|
table: type[StatisticsBase],
|
||||||
metadata_id: int,
|
metadata_id: int,
|
||||||
statistic: StatisticData,
|
statistic: StatisticData,
|
||||||
|
now_timestamp: float,
|
||||||
) -> StatisticsBase | None:
|
) -> StatisticsBase | None:
|
||||||
"""Insert statistics in the database."""
|
"""Insert statistics in the database."""
|
||||||
try:
|
try:
|
||||||
stat = table.from_stats(metadata_id, statistic)
|
stat = table.from_stats(metadata_id, statistic, now_timestamp)
|
||||||
session.add(stat)
|
session.add(stat)
|
||||||
except SQLAlchemyError:
|
except SQLAlchemyError:
|
||||||
_LOGGER.exception(
|
_LOGGER.exception(
|
||||||
@ -2347,11 +2348,12 @@ def _import_statistics_with_session(
|
|||||||
_, metadata_id = statistics_meta_manager.update_or_add(
|
_, metadata_id = statistics_meta_manager.update_or_add(
|
||||||
session, metadata, old_metadata_dict
|
session, metadata, old_metadata_dict
|
||||||
)
|
)
|
||||||
|
now_timestamp = time_time()
|
||||||
for stat in statistics:
|
for stat in statistics:
|
||||||
if stat_id := _statistics_exists(session, table, metadata_id, stat["start"]):
|
if stat_id := _statistics_exists(session, table, metadata_id, stat["start"]):
|
||||||
_update_statistics(session, table, stat_id, stat)
|
_update_statistics(session, table, stat_id, stat)
|
||||||
else:
|
else:
|
||||||
_insert_statistics(session, table, metadata_id, stat)
|
_insert_statistics(session, table, metadata_id, stat, now_timestamp)
|
||||||
|
|
||||||
if table != StatisticsShortTerm:
|
if table != StatisticsShortTerm:
|
||||||
return True
|
return True
|
||||||
|
@ -337,12 +337,12 @@ def mock_from_stats():
|
|||||||
counter = 0
|
counter = 0
|
||||||
real_from_stats = StatisticsShortTerm.from_stats
|
real_from_stats = StatisticsShortTerm.from_stats
|
||||||
|
|
||||||
def from_stats(metadata_id, stats):
|
def from_stats(metadata_id, stats, now_timestamp):
|
||||||
nonlocal counter
|
nonlocal counter
|
||||||
if counter == 0 and metadata_id == 2:
|
if counter == 0 and metadata_id == 2:
|
||||||
counter += 1
|
counter += 1
|
||||||
return None
|
return None
|
||||||
return real_from_stats(metadata_id, stats)
|
return real_from_stats(metadata_id, stats, now_timestamp)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.recorder.statistics.StatisticsShortTerm.from_stats",
|
"homeassistant.components.recorder.statistics.StatisticsShortTerm.from_stats",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user