From 33450c726dd93fd79eee0e457c8b1926c0a739cf Mon Sep 17 00:00:00 2001 From: Nathan Henrie Date: Wed, 15 Mar 2017 01:14:12 -0600 Subject: [PATCH] Use sqlite's WAL mode to avoid `database is locked` errors (#6519) * Use sqlite's WAL mode to avoid `database is locked` errors - Relevant issue: https://github.com/home-assistant/home-assistant/issues/4780 Code: - http://stackoverflow.com/a/23661501/1588795 - http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#foreign-key-support - https://github.com/g2p/bedup/pull/86/files * Only set WAL if using sqlite * Reorder imports * Fix pylint warnings --- homeassistant/components/recorder/__init__.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index de093a8c943..8ac610f1bcf 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -287,13 +287,27 @@ class Recorder(threading.Thread): def _setup_connection(self): """Ensure database is ready to fly.""" - from sqlalchemy import create_engine + from sqlalchemy import create_engine, event + from sqlalchemy.engine import Engine from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker + from . import models kwargs = {} + # pylint: disable=unused-variable + @event.listens_for(Engine, "connect") + def set_sqlite_pragma(dbapi_connection, connection_record): + """Set sqlite's WAL mode.""" + if self.db_url.startswith("sqlite://"): + old_isolation = dbapi_connection.isolation_level + dbapi_connection.isolation_level = None + cursor = dbapi_connection.cursor() + cursor.execute("PRAGMA journal_mode=WAL") + cursor.close() + dbapi_connection.isolation_level = old_isolation + if self.db_url == 'sqlite://' or ':memory:' in self.db_url: from sqlalchemy.pool import StaticPool