Skip to content

Commit bb93d46

Browse files
committed
Add test_sensor.test_multiple_sensors_using_same_external_db
Signed-off-by: David Rapan <[email protected]>
1 parent cc11b85 commit bb93d46

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

homeassistant/components/sql/sensor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,10 @@ def _process(self, result: Result) -> None:
279279
_LOGGER.warning("%s returned no results", self._query)
280280

281281
def _update(self) -> None:
282-
"""Retrieve sensor data from the query."""
283-
self._attr_extra_state_attributes = {}
282+
"""Retrieve sensor data from the query.
283+
284+
This does I/O and should be run in the executor.
285+
"""
284286
if TYPE_CHECKING:
285287
assert isinstance(self.sessionmaker, scoped_session)
286288
with self.sessionmaker() as session:
@@ -296,8 +298,8 @@ def _update(self) -> None:
296298

297299
async def async_update(self) -> None:
298300
"""Retrieve sensor data from the query using the right executor."""
301+
self._attr_extra_state_attributes = {}
299302
if isinstance(self.sessionmaker, async_scoped_session):
300-
self._attr_extra_state_attributes = {}
301303
async with self.sessionmaker() as session:
302304
try:
303305
self._process(await session.execute(self._lambda_stmt))

homeassistant/components/sql/util.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ async def _async_validate_and_get_session_maker_for_db_url(
215215
"""Validate the db_url and return a async session maker."""
216216
try:
217217
maker = async_scoped_session(
218-
async_sessionmaker(bind=create_async_engine(db_url)),
218+
async_sessionmaker(
219+
bind=create_async_engine(db_url, future=True), future=True
220+
),
219221
scopefunc=asyncio.current_task,
220222
)
221223
# Run a dummy query just to test the db_url

tests/components/sql/test_sensor.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,53 @@ async def test_multiple_sensors_using_same_db(
638638
await hass.async_stop()
639639

640640

641+
async def test_multiple_sensors_using_same_external_db(
642+
recorder_mock: Recorder, hass: HomeAssistant, tmp_path: Path
643+
) -> None:
644+
"""Test multiple sensors using the same external db."""
645+
db_path = tmp_path / "test.db"
646+
647+
# Create and populate the external database
648+
conn = sqlite3.connect(db_path)
649+
conn.execute("CREATE TABLE users (name TEXT, age INTEGER)")
650+
conn.execute("INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 25)")
651+
conn.commit()
652+
conn.close()
653+
654+
config = {CONF_DB_URL: f"sqlite:///{db_path}"}
655+
config2 = {CONF_DB_URL: f"sqlite:///{db_path}"}
656+
options = {
657+
CONF_QUERY: "SELECT name FROM users ORDER BY age LIMIT 1",
658+
CONF_COLUMN_NAME: "name",
659+
}
660+
options2 = {
661+
CONF_QUERY: "SELECT name FROM users ORDER BY age DESC LIMIT 1",
662+
CONF_COLUMN_NAME: "name",
663+
}
664+
665+
await init_integration(
666+
hass, title="Select name SQL query", config=config, options=options
667+
)
668+
669+
assert hass.data["sql"]
670+
assert len(hass.data["sql"].session_makers_by_db_url) == 1
671+
assert hass.states.get("sensor.select_name_sql_query").state == "Bob"
672+
673+
await init_integration(
674+
hass,
675+
title="Select name SQL query 2",
676+
config=config2,
677+
options=options2,
678+
entry_id="2",
679+
)
680+
681+
assert len(hass.data["sql"].session_makers_by_db_url) == 1
682+
assert hass.states.get("sensor.select_name_sql_query_2").state == "Alice"
683+
684+
with patch("sqlalchemy.engine.base.Engine.dispose"):
685+
await hass.async_stop()
686+
687+
641688
async def test_engine_is_disposed_at_stop(
642689
recorder_mock: Recorder, hass: HomeAssistant
643690
) -> None:

0 commit comments

Comments
 (0)