From 75e0c50e6ea22b2ff8e7da35610a286a007d34f1 Mon Sep 17 00:00:00 2001 From: Deimos Date: Wed, 22 Aug 2018 22:33:59 -0600 Subject: [PATCH] Add log_comments table (and LogComment class) --- .../b3be50625592_add_log_comments_table.py | 58 +++++++++++++++++++ tildes/scripts/initialize_db.py | 5 +- tildes/tildes/models/log/__init__.py | 2 +- tildes/tildes/models/log/log.py | 53 ++++++++++++++++- 4 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 tildes/alembic/versions/b3be50625592_add_log_comments_table.py diff --git a/tildes/alembic/versions/b3be50625592_add_log_comments_table.py b/tildes/alembic/versions/b3be50625592_add_log_comments_table.py new file mode 100644 index 0000000..966aba0 --- /dev/null +++ b/tildes/alembic/versions/b3be50625592_add_log_comments_table.py @@ -0,0 +1,58 @@ +"""Add log_comments table + +Revision ID: b3be50625592 +Revises: a1708d376252 +Create Date: 2018-08-23 04:20:55.819209 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "b3be50625592" +down_revision = "a1708d376252" +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("CREATE TABLE log_comments (comment_id integer not null) INHERITS (log)") + op.create_foreign_key( + op.f("fk_log_comments_comment_id_comments"), + "log_comments", + "comments", + ["comment_id"], + ["comment_id"], + ) + op.create_index( + op.f("ix_log_comments_comment_id"), "log_comments", ["comment_id"], unique=False + ) + + # duplicate all the indexes/constraints from the base log table + op.create_primary_key(op.f("pk_log_comments"), "log_comments", ["log_id"]) + op.create_index( + op.f("ix_log_comments_event_time"), "log_comments", ["event_time"], unique=False + ) + op.create_index( + op.f("ix_log_comments_event_type"), "log_comments", ["event_type"], unique=False + ) + op.create_index( + op.f("ix_log_comments_ip_address"), "log_comments", ["ip_address"], unique=False + ) + op.create_index( + op.f("ix_log_comments_user_id"), "log_comments", ["user_id"], unique=False + ) + + op.create_foreign_key( + op.f("fk_log_comments_user_id_users"), + "log_comments", + "users", + ["user_id"], + ["user_id"], + ) + + +def downgrade(): + op.drop_index(op.f("ix_log_comments_comment_id"), table_name="log_comments") + op.drop_table("log_comments") diff --git a/tildes/scripts/initialize_db.py b/tildes/scripts/initialize_db.py index 6f4f472..3df4b27 100644 --- a/tildes/scripts/initialize_db.py +++ b/tildes/scripts/initialize_db.py @@ -38,7 +38,7 @@ def initialize_db(config_path: str, alembic_config_path: Optional[str] = None) - def create_tables(connectable: Connectable) -> None: """Create the database tables.""" # tables to skip (due to inheritance or other need to create manually) - excluded_tables = Log.INHERITED_TABLES + excluded_tables = Log.INHERITED_TABLES + ["log"] tables = [ table @@ -47,6 +47,9 @@ def create_tables(connectable: Connectable) -> None: ] DatabaseModel.metadata.create_all(connectable, tables=tables) + # create log table (and inherited ones) last + DatabaseModel.metadata.create_all(connectable, tables=[Log.__table__]) + def run_sql_scripts_in_dir(path: str, engine: Engine) -> None: """Run all sql scripts in a directory.""" diff --git a/tildes/tildes/models/log/__init__.py b/tildes/tildes/models/log/__init__.py index a6e3c6b..19a363e 100644 --- a/tildes/tildes/models/log/__init__.py +++ b/tildes/tildes/models/log/__init__.py @@ -1,3 +1,3 @@ """Contains models related to logs.""" -from .log import Log, LogTopic +from .log import Log, LogComment, LogTopic diff --git a/tildes/tildes/models/log/log.py b/tildes/tildes/models/log/log.py index 257dd91..e7faec5 100644 --- a/tildes/tildes/models/log/log.py +++ b/tildes/tildes/models/log/log.py @@ -13,6 +13,7 @@ from sqlalchemy.sql.expression import text from tildes.enums import LogEventType from tildes.models import DatabaseModel +from tildes.models.comment import Comment from tildes.models.topic import Topic @@ -65,7 +66,7 @@ class Log(DatabaseModel, BaseLog): __tablename__ = "log" - INHERITED_TABLES = ["log_topics"] + INHERITED_TABLES = ["log_comments", "log_topics"] def __init__( self, @@ -86,6 +87,35 @@ class Log(DatabaseModel, BaseLog): self.info = info +class LogComment(DatabaseModel, BaseLog): + """Model for a log entry related to a specific comment.""" + + __tablename__ = "log_comments" + + comment_id: int = Column( + Integer, ForeignKey("comments.comment_id"), index=True, nullable=False + ) + + comment: Comment = relationship("Comment") + + def __init__( + self, + event_type: LogEventType, + request: Request, + comment: Comment, + info: Optional[Dict[str, Any]] = None, + ) -> None: + """Create a new log entry related to a specific comment.""" + # pylint: disable=non-parent-init-called + Log.__init__(self, event_type, request, info) + + self.comment = comment + + def __str__(self) -> str: + """Return a string representation of the log event.""" + return f"performed action {self.event_type.name}" # noqa + + class LogTopic(DatabaseModel, BaseLog): """Model for a log entry related to a specific topic.""" @@ -192,6 +222,27 @@ def create_inherited_tables( ix_name = naming["ix"] % {"table_name": "log_topics", "column_0_name": "topic_id"} connection.execute(f"CREATE INDEX {ix_name} ON log_topics (topic_id)") + # log_comments + connection.execute( + "CREATE TABLE log_comments (comment_id integer not null) INHERITS (log)" + ) + + fk_name = naming["fk"] % { + "table_name": "log_comments", + "column_0_name": "comment_id", + "referred_table_name": "comments", + } + connection.execute( + f"ALTER TABLE log_comments ADD CONSTRAINT {fk_name} " + "FOREIGN KEY (comment_id) REFERENCES comments (comment_id)" + ) + + ix_name = naming["ix"] % { + "table_name": "log_comments", + "column_0_name": "comment_id", + } + connection.execute(f"CREATE INDEX {ix_name} ON log_comments (comment_id)") + # duplicate all the indexes/constraints from the base log table for table in Log.INHERITED_TABLES: pk_name = naming["pk"] % {"table_name": table}