Add support for Oracle DB in recorder (#50090)
parent
460092ec9a
commit
caad125b44
|
@ -500,10 +500,10 @@ def _generate_events_query(session):
|
||||||
def _generate_events_query_without_states(session):
|
def _generate_events_query_without_states(session):
|
||||||
return session.query(
|
return session.query(
|
||||||
*EVENT_COLUMNS,
|
*EVENT_COLUMNS,
|
||||||
literal(None).label("state"),
|
literal(value=None, type_=sqlalchemy.String).label("state"),
|
||||||
literal(None).label("entity_id"),
|
literal(value=None, type_=sqlalchemy.String).label("entity_id"),
|
||||||
literal(None).label("domain"),
|
literal(value=None, type_=sqlalchemy.String).label("domain"),
|
||||||
literal(None).label("attributes"),
|
literal(value=None, type_=sqlalchemy.Text).label("attributes"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,34 @@ def _update_states_table_with_foreign_key_options(connection, engine):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _drop_foreign_key_constraints(connection, engine, table, columns):
|
||||||
|
"""Drop foreign key constraints for a table on specific columns."""
|
||||||
|
inspector = sqlalchemy.inspect(engine)
|
||||||
|
drops = []
|
||||||
|
for foreign_key in inspector.get_foreign_keys(table):
|
||||||
|
if (
|
||||||
|
foreign_key["name"]
|
||||||
|
and foreign_key["options"].get("ondelete")
|
||||||
|
and foreign_key["constrained_columns"] == columns
|
||||||
|
):
|
||||||
|
drops.append(ForeignKeyConstraint((), (), name=foreign_key["name"]))
|
||||||
|
|
||||||
|
# Bind the ForeignKeyConstraints to the table
|
||||||
|
old_table = Table( # noqa: F841 pylint: disable=unused-variable
|
||||||
|
table, MetaData(), *drops
|
||||||
|
)
|
||||||
|
|
||||||
|
for drop in drops:
|
||||||
|
try:
|
||||||
|
connection.execute(DropConstraint(drop))
|
||||||
|
except (InternalError, OperationalError):
|
||||||
|
_LOGGER.exception(
|
||||||
|
"Could not drop foreign constraints in %s table on %s",
|
||||||
|
TABLE_STATES,
|
||||||
|
columns,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _apply_update(engine, session, new_version, old_version):
|
def _apply_update(engine, session, new_version, old_version):
|
||||||
"""Perform operations to bring schema up to date."""
|
"""Perform operations to bring schema up to date."""
|
||||||
connection = session.connection()
|
connection = session.connection()
|
||||||
|
@ -420,6 +448,10 @@ def _apply_update(engine, session, new_version, old_version):
|
||||||
# Recreate the statistics table
|
# Recreate the statistics table
|
||||||
Statistics.__table__.drop(engine)
|
Statistics.__table__.drop(engine)
|
||||||
Statistics.__table__.create(engine)
|
Statistics.__table__.create(engine)
|
||||||
|
elif new_version == 16:
|
||||||
|
_drop_foreign_key_constraints(
|
||||||
|
connection, engine, TABLE_STATES, ["old_state_id"]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"No schema migration defined for version {new_version}")
|
raise ValueError(f"No schema migration defined for version {new_version}")
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ from sqlalchemy import (
|
||||||
DateTime,
|
DateTime,
|
||||||
Float,
|
Float,
|
||||||
ForeignKey,
|
ForeignKey,
|
||||||
|
Identity,
|
||||||
Index,
|
Index,
|
||||||
Integer,
|
Integer,
|
||||||
String,
|
String,
|
||||||
|
@ -28,7 +29,7 @@ import homeassistant.util.dt as dt_util
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
SCHEMA_VERSION = 15
|
SCHEMA_VERSION = 16
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ class Events(Base): # type: ignore
|
||||||
"mysql_collate": "utf8mb4_unicode_ci",
|
"mysql_collate": "utf8mb4_unicode_ci",
|
||||||
}
|
}
|
||||||
__tablename__ = TABLE_EVENTS
|
__tablename__ = TABLE_EVENTS
|
||||||
event_id = Column(Integer, primary_key=True)
|
event_id = Column(Integer, Identity(), primary_key=True)
|
||||||
event_type = Column(String(MAX_LENGTH_EVENT_TYPE))
|
event_type = Column(String(MAX_LENGTH_EVENT_TYPE))
|
||||||
event_data = Column(Text().with_variant(mysql.LONGTEXT, "mysql"))
|
event_data = Column(Text().with_variant(mysql.LONGTEXT, "mysql"))
|
||||||
origin = Column(String(32))
|
origin = Column(String(32))
|
||||||
|
@ -128,7 +129,7 @@ class States(Base): # type: ignore
|
||||||
"mysql_collate": "utf8mb4_unicode_ci",
|
"mysql_collate": "utf8mb4_unicode_ci",
|
||||||
}
|
}
|
||||||
__tablename__ = TABLE_STATES
|
__tablename__ = TABLE_STATES
|
||||||
state_id = Column(Integer, primary_key=True)
|
state_id = Column(Integer, Identity(), primary_key=True)
|
||||||
domain = Column(String(64))
|
domain = Column(String(64))
|
||||||
entity_id = Column(String(255))
|
entity_id = Column(String(255))
|
||||||
state = Column(String(255))
|
state = Column(String(255))
|
||||||
|
@ -139,9 +140,7 @@ class States(Base): # type: ignore
|
||||||
last_changed = Column(DATETIME_TYPE, default=dt_util.utcnow)
|
last_changed = Column(DATETIME_TYPE, default=dt_util.utcnow)
|
||||||
last_updated = Column(DATETIME_TYPE, default=dt_util.utcnow, index=True)
|
last_updated = Column(DATETIME_TYPE, default=dt_util.utcnow, index=True)
|
||||||
created = Column(DATETIME_TYPE, default=dt_util.utcnow)
|
created = Column(DATETIME_TYPE, default=dt_util.utcnow)
|
||||||
old_state_id = Column(
|
old_state_id = Column(Integer, ForeignKey("states.state_id"), index=True)
|
||||||
Integer, ForeignKey("states.state_id", ondelete="NO ACTION"), index=True
|
|
||||||
)
|
|
||||||
event = relationship("Events", uselist=False)
|
event = relationship("Events", uselist=False)
|
||||||
old_state = relationship("States", remote_side=[state_id])
|
old_state = relationship("States", remote_side=[state_id])
|
||||||
|
|
||||||
|
@ -246,7 +245,7 @@ class RecorderRuns(Base): # type: ignore
|
||||||
"""Representation of recorder run."""
|
"""Representation of recorder run."""
|
||||||
|
|
||||||
__tablename__ = TABLE_RECORDER_RUNS
|
__tablename__ = TABLE_RECORDER_RUNS
|
||||||
run_id = Column(Integer, primary_key=True)
|
run_id = Column(Integer, Identity(), primary_key=True)
|
||||||
start = Column(DateTime(timezone=True), default=dt_util.utcnow)
|
start = Column(DateTime(timezone=True), default=dt_util.utcnow)
|
||||||
end = Column(DateTime(timezone=True))
|
end = Column(DateTime(timezone=True))
|
||||||
closed_incorrect = Column(Boolean, default=False)
|
closed_incorrect = Column(Boolean, default=False)
|
||||||
|
@ -297,7 +296,7 @@ class SchemaChanges(Base): # type: ignore
|
||||||
"""Representation of schema version changes."""
|
"""Representation of schema version changes."""
|
||||||
|
|
||||||
__tablename__ = TABLE_SCHEMA_CHANGES
|
__tablename__ = TABLE_SCHEMA_CHANGES
|
||||||
change_id = Column(Integer, primary_key=True)
|
change_id = Column(Integer, Identity(), primary_key=True)
|
||||||
schema_version = Column(Integer)
|
schema_version = Column(Integer)
|
||||||
changed = Column(DateTime(timezone=True), default=dt_util.utcnow)
|
changed = Column(DateTime(timezone=True), default=dt_util.utcnow)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue