Add support for Oracle DB in recorder (#50090)

pull/50986/head
Marcin Ciupak 2021-05-23 04:10:27 +02:00 committed by GitHub
parent 460092ec9a
commit caad125b44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 12 deletions

View File

@ -500,10 +500,10 @@ def _generate_events_query(session):
def _generate_events_query_without_states(session):
return session.query(
*EVENT_COLUMNS,
literal(None).label("state"),
literal(None).label("entity_id"),
literal(None).label("domain"),
literal(None).label("attributes"),
literal(value=None, type_=sqlalchemy.String).label("state"),
literal(value=None, type_=sqlalchemy.String).label("entity_id"),
literal(value=None, type_=sqlalchemy.String).label("domain"),
literal(value=None, type_=sqlalchemy.Text).label("attributes"),
)

View File

@ -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):
"""Perform operations to bring schema up to date."""
connection = session.connection()
@ -420,6 +448,10 @@ def _apply_update(engine, session, new_version, old_version):
# Recreate the statistics table
Statistics.__table__.drop(engine)
Statistics.__table__.create(engine)
elif new_version == 16:
_drop_foreign_key_constraints(
connection, engine, TABLE_STATES, ["old_state_id"]
)
else:
raise ValueError(f"No schema migration defined for version {new_version}")

View File

@ -8,6 +8,7 @@ from sqlalchemy import (
DateTime,
Float,
ForeignKey,
Identity,
Index,
Integer,
String,
@ -28,7 +29,7 @@ import homeassistant.util.dt as dt_util
# pylint: disable=invalid-name
Base = declarative_base()
SCHEMA_VERSION = 15
SCHEMA_VERSION = 16
_LOGGER = logging.getLogger(__name__)
@ -61,7 +62,7 @@ class Events(Base): # type: ignore
"mysql_collate": "utf8mb4_unicode_ci",
}
__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_data = Column(Text().with_variant(mysql.LONGTEXT, "mysql"))
origin = Column(String(32))
@ -128,7 +129,7 @@ class States(Base): # type: ignore
"mysql_collate": "utf8mb4_unicode_ci",
}
__tablename__ = TABLE_STATES
state_id = Column(Integer, primary_key=True)
state_id = Column(Integer, Identity(), primary_key=True)
domain = Column(String(64))
entity_id = 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_updated = Column(DATETIME_TYPE, default=dt_util.utcnow, index=True)
created = Column(DATETIME_TYPE, default=dt_util.utcnow)
old_state_id = Column(
Integer, ForeignKey("states.state_id", ondelete="NO ACTION"), index=True
)
old_state_id = Column(Integer, ForeignKey("states.state_id"), index=True)
event = relationship("Events", uselist=False)
old_state = relationship("States", remote_side=[state_id])
@ -246,7 +245,7 @@ class RecorderRuns(Base): # type: ignore
"""Representation of recorder run."""
__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)
end = Column(DateTime(timezone=True))
closed_incorrect = Column(Boolean, default=False)
@ -297,7 +296,7 @@ class SchemaChanges(Base): # type: ignore
"""Representation of schema version changes."""
__tablename__ = TABLE_SCHEMA_CHANGES
change_id = Column(Integer, primary_key=True)
change_id = Column(Integer, Identity(), primary_key=True)
schema_version = Column(Integer)
changed = Column(DateTime(timezone=True), default=dt_util.utcnow)