Switch sqlalchemy execute to use .all() instead of list() on the iterator (#68540)

pull/68355/head^2
J. Nick Koston 2022-03-22 19:24:21 -10:00 committed by GitHub
parent dd1d7fdbab
commit 7deeb92485
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 8 additions and 5 deletions

View File

@ -17,6 +17,7 @@ from awesomeversion import (
) )
from sqlalchemy import text from sqlalchemy import text
from sqlalchemy.exc import OperationalError, SQLAlchemyError from sqlalchemy.exc import OperationalError, SQLAlchemyError
from sqlalchemy.orm.query import Query
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -111,12 +112,13 @@ def commit(session, work):
return False return False
def execute(qry, to_native=False, validate_entity_ids=True) -> list | None: def execute(
qry: Query, to_native: bool = False, validate_entity_ids: bool = True
) -> list | None:
"""Query the database and convert the objects to HA native form. """Query the database and convert the objects to HA native form.
This method also retries a few times in the case of stale connections. This method also retries a few times in the case of stale connections.
""" """
for tryno in range(0, RETRIES): for tryno in range(0, RETRIES):
try: try:
timer_start = time.perf_counter() timer_start = time.perf_counter()
@ -130,7 +132,7 @@ def execute(qry, to_native=False, validate_entity_ids=True) -> list | None:
if row is not None if row is not None
] ]
else: else:
result = list(qry) result = qry.all()
if _LOGGER.isEnabledFor(logging.DEBUG): if _LOGGER.isEnabledFor(logging.DEBUG):
elapsed = time.perf_counter() - timer_start elapsed = time.perf_counter() - timer_start
@ -427,6 +429,7 @@ def retryable_database_job(description: str) -> Callable:
try: try:
return job(instance, *args, **kwargs) return job(instance, *args, **kwargs)
except OperationalError as err: except OperationalError as err:
assert instance.engine is not None
if ( if (
instance.engine.dialect.name == "mysql" instance.engine.dialect.name == "mysql"
and err.orig.args[0] in RETRYABLE_MYSQL_ERRORS and err.orig.args[0] in RETRYABLE_MYSQL_ERRORS
@ -453,7 +456,7 @@ def perodic_db_cleanups(instance: Recorder):
These cleanups will happen nightly or after any purge. These cleanups will happen nightly or after any purge.
""" """
assert instance.engine is not None
if instance.engine.dialect.name == "sqlite": if instance.engine.dialect.name == "sqlite":
# Execute sqlite to create a wal checkpoint and free up disk space # Execute sqlite to create a wal checkpoint and free up disk space
_LOGGER.debug("WAL checkpoint") _LOGGER.debug("WAL checkpoint")
@ -464,7 +467,7 @@ def perodic_db_cleanups(instance: Recorder):
@contextmanager @contextmanager
def write_lock_db_sqlite(instance: Recorder): def write_lock_db_sqlite(instance: Recorder):
"""Lock database for writes.""" """Lock database for writes."""
assert instance.engine is not None
with instance.engine.connect() as connection: with instance.engine.connect() as connection:
# Execute sqlite to create a wal checkpoint # Execute sqlite to create a wal checkpoint
# This is optional but makes sure the backup is going to be minimal # This is optional but makes sure the backup is going to be minimal