Additional prep work for sqlalchemy 2.0 (#70358)

This commit is contained in:
J. Nick Koston 2022-04-21 12:39:18 -10:00 committed by GitHub
parent 034ba7d3ff
commit 3142a106fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 13 deletions

View File

@ -1436,12 +1436,12 @@ class Recorder(threading.Thread):
if self._using_file_sqlite: if self._using_file_sqlite:
validate_or_move_away_sqlite_database(self.db_url) validate_or_move_away_sqlite_database(self.db_url)
self.engine = create_engine(self.db_url, **kwargs) self.engine = create_engine(self.db_url, **kwargs, future=True)
sqlalchemy_event.listen(self.engine, "connect", setup_recorder_connection) sqlalchemy_event.listen(self.engine, "connect", setup_recorder_connection)
Base.metadata.create_all(self.engine) Base.metadata.create_all(self.engine)
self.get_session = scoped_session(sessionmaker(bind=self.engine)) self.get_session = scoped_session(sessionmaker(bind=self.engine, future=True))
_LOGGER.debug("Connected to recorder database") _LOGGER.debug("Connected to recorder database")
@property @property

View File

@ -4,6 +4,8 @@ from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from sqlalchemy import text
if TYPE_CHECKING: if TYPE_CHECKING:
from . import Recorder from . import Recorder
@ -18,7 +20,9 @@ def repack_database(instance: Recorder) -> None:
# Execute sqlite command to free up space on disk # Execute sqlite command to free up space on disk
if dialect_name == "sqlite": if dialect_name == "sqlite":
_LOGGER.debug("Vacuuming SQL DB to free space") _LOGGER.debug("Vacuuming SQL DB to free space")
instance.engine.execute("VACUUM") with instance.engine.connect() as conn:
conn.execute(text("VACUUM"))
conn.commit()
return return
# Execute postgresql vacuum command to free up space on disk # Execute postgresql vacuum command to free up space on disk
@ -27,11 +31,14 @@ def repack_database(instance: Recorder) -> None:
with instance.engine.connect().execution_options( with instance.engine.connect().execution_options(
isolation_level="AUTOCOMMIT" isolation_level="AUTOCOMMIT"
) as conn: ) as conn:
conn.execute("VACUUM") conn.execute(text("VACUUM"))
conn.commit()
return return
# Optimize mysql / mariadb tables to free up space on disk # Optimize mysql / mariadb tables to free up space on disk
if dialect_name == "mysql": if dialect_name == "mysql":
_LOGGER.debug("Optimizing SQL DB to free space") _LOGGER.debug("Optimizing SQL DB to free space")
instance.engine.execute("OPTIMIZE TABLE states, events, recorder_runs") with instance.engine.connect() as conn:
conn.execute(text("OPTIMIZE TABLE states, events, recorder_runs"))
conn.commit()
return return

View File

@ -6,6 +6,7 @@ import json
from unittest.mock import patch, sentinel from unittest.mock import patch, sentinel
import pytest import pytest
from sqlalchemy import text
from homeassistant.components import recorder from homeassistant.components import recorder
from homeassistant.components.recorder import history from homeassistant.components.recorder import history
@ -628,8 +629,10 @@ async def test_state_changes_during_period_query_during_migration_to_schema_25(
state = hist[entity_id][0] state = hist[entity_id][0]
assert state.attributes == {"name": "the shared light"} assert state.attributes == {"name": "the shared light"}
instance.engine.execute("update states set attributes_id=NULL;") with instance.engine.connect() as conn:
instance.engine.execute("drop table state_attributes;") conn.execute(text("update states set attributes_id=NULL;"))
conn.execute(text("drop table state_attributes;"))
conn.commit()
with patch.object(instance, "migration_in_progress", True): with patch.object(instance, "migration_in_progress", True):
no_attributes = True no_attributes = True
@ -670,8 +673,10 @@ async def test_get_states_query_during_migration_to_schema_25(
state = hist[0] state = hist[0]
assert state.attributes == {"name": "the shared light"} assert state.attributes == {"name": "the shared light"}
instance.engine.execute("update states set attributes_id=NULL;") with instance.engine.connect() as conn:
instance.engine.execute("drop table state_attributes;") conn.execute(text("update states set attributes_id=NULL;"))
conn.execute(text("drop table state_attributes;"))
conn.commit()
with patch.object(instance, "migration_in_progress", True): with patch.object(instance, "migration_in_progress", True):
no_attributes = True no_attributes = True
@ -711,8 +716,10 @@ async def test_get_states_query_during_migration_to_schema_25_multiple_entities(
assert hist[0].attributes == {"name": "the shared light"} assert hist[0].attributes == {"name": "the shared light"}
assert hist[1].attributes == {"name": "the shared light"} assert hist[1].attributes == {"name": "the shared light"}
instance.engine.execute("update states set attributes_id=NULL;") with instance.engine.connect() as conn:
instance.engine.execute("drop table state_attributes;") conn.execute(text("update states set attributes_id=NULL;"))
conn.execute(text("drop table state_attributes;"))
conn.commit()
with patch.object(instance, "migration_in_progress", True): with patch.object(instance, "migration_in_progress", True):
no_attributes = True no_attributes = True

View File

@ -49,7 +49,7 @@ async def test_purge_old_states(
assert states.count() == 6 assert states.count() == 6
assert states[0].old_state_id is None assert states[0].old_state_id is None
assert states[-1].old_state_id == states[-2].state_id assert states[5].old_state_id == states[4].state_id
assert state_attributes.count() == 3 assert state_attributes.count() == 3
events = session.query(Events).filter(Events.event_type == "state_changed") events = session.query(Events).filter(Events.event_type == "state_changed")
@ -94,7 +94,7 @@ async def test_purge_old_states(
states = session.query(States) states = session.query(States)
assert states.count() == 6 assert states.count() == 6
assert states[0].old_state_id is None assert states[0].old_state_id is None
assert states[-1].old_state_id == states[-2].state_id assert states[5].old_state_id == states[4].state_id
events = session.query(Events).filter(Events.event_type == "state_changed") events = session.query(Events).filter(Events.event_type == "state_changed")
assert events.count() == 6 assert events.count() == 6