mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 18:28:14 +02:00
Guard against db corruption when renaming entities (#112718)
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, Collection, Generator, Iterable, Sequence
|
||||
import contextlib
|
||||
from contextlib import contextmanager
|
||||
from datetime import date, datetime, timedelta
|
||||
import functools
|
||||
@ -22,7 +23,7 @@ import ciso8601
|
||||
from sqlalchemy import inspect, text
|
||||
from sqlalchemy.engine import Result, Row
|
||||
from sqlalchemy.engine.interfaces import DBAPIConnection
|
||||
from sqlalchemy.exc import OperationalError, SQLAlchemyError
|
||||
from sqlalchemy.exc import OperationalError, SQLAlchemyError, StatementError
|
||||
from sqlalchemy.orm.query import Query
|
||||
from sqlalchemy.orm.session import Session
|
||||
from sqlalchemy.sql.lambdas import StatementLambdaElement
|
||||
@ -907,3 +908,54 @@ def get_index_by_name(session: Session, table_name: str, index_name: str) -> str
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
def filter_unique_constraint_integrity_error(
|
||||
instance: Recorder, row_type: str
|
||||
) -> Callable[[Exception], bool]:
|
||||
"""Create a filter for unique constraint integrity errors."""
|
||||
|
||||
def _filter_unique_constraint_integrity_error(err: Exception) -> bool:
|
||||
"""Handle unique constraint integrity errors."""
|
||||
if not isinstance(err, StatementError):
|
||||
return False
|
||||
|
||||
assert instance.engine is not None
|
||||
dialect_name = instance.engine.dialect.name
|
||||
|
||||
ignore = False
|
||||
if (
|
||||
dialect_name == SupportedDialect.SQLITE
|
||||
and "UNIQUE constraint failed" in str(err)
|
||||
):
|
||||
ignore = True
|
||||
if (
|
||||
dialect_name == SupportedDialect.POSTGRESQL
|
||||
and err.orig
|
||||
and hasattr(err.orig, "pgcode")
|
||||
and err.orig.pgcode == "23505"
|
||||
):
|
||||
ignore = True
|
||||
if (
|
||||
dialect_name == SupportedDialect.MYSQL
|
||||
and err.orig
|
||||
and hasattr(err.orig, "args")
|
||||
):
|
||||
with contextlib.suppress(TypeError):
|
||||
if err.orig.args[0] == 1062:
|
||||
ignore = True
|
||||
|
||||
if ignore:
|
||||
_LOGGER.warning(
|
||||
(
|
||||
"Blocked attempt to insert duplicated %s rows, please report"
|
||||
" at %s"
|
||||
),
|
||||
row_type,
|
||||
"https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+recorder%22",
|
||||
exc_info=err,
|
||||
)
|
||||
|
||||
return ignore
|
||||
|
||||
return _filter_unique_constraint_integrity_error
|
||||
|
Reference in New Issue
Block a user