topic: Move sqlalchemy methods into their own file.

Loading sqlalchemy can take a significant amount of time, so splitting
these into these own file can be a significant startup-time savings.
This commit is contained in:
Alex Vandiver 2024-04-15 19:40:37 +00:00 committed by Tim Abbott
parent 1abd356a91
commit 57ff573535
6 changed files with 26 additions and 23 deletions

View File

@ -13,6 +13,7 @@ from zulint.custom_rules import Rule, RuleList
FILES_WITH_LEGACY_SUBJECT = { FILES_WITH_LEGACY_SUBJECT = {
# This basically requires a big DB migration: # This basically requires a big DB migration:
"zerver/lib/topic.py", "zerver/lib/topic.py",
"zerver/lib/topic_sqlalchemy.py",
# This is for backward compatibility. # This is for backward compatibility.
"zerver/tests/test_legacy_subject.py", "zerver/tests/test_legacy_subject.py",
# Other migration-related changes require extreme care. # Other migration-related changes require extreme care.

View File

@ -58,10 +58,9 @@ from zerver.lib.streams import (
get_stream_by_narrow_operand_access_unchecked, get_stream_by_narrow_operand_access_unchecked,
get_web_public_streams_queryset, get_web_public_streams_queryset,
) )
from zerver.lib.topic import ( from zerver.lib.topic import RESOLVED_TOPIC_PREFIX, get_topic_from_message_info
RESOLVED_TOPIC_PREFIX, from zerver.lib.topic_sqlalchemy import (
get_resolved_topic_condition_sa, get_resolved_topic_condition_sa,
get_topic_from_message_info,
topic_column_sa, topic_column_sa,
topic_match_sa, topic_match_sa,
) )

View File

@ -5,8 +5,6 @@ import orjson
from django.db import connection from django.db import connection
from django.db.models import F, Func, JSONField, Q, QuerySet, Subquery, TextField, Value from django.db.models import F, Func, JSONField, Q, QuerySet, Subquery, TextField, Value
from django.db.models.functions import Cast from django.db.models.functions import Cast
from sqlalchemy.sql import ColumnElement, column, func, literal
from sqlalchemy.types import Boolean, Text
from zerver.lib.request import REQ from zerver.lib.request import REQ
from zerver.lib.types import EditHistoryEvent from zerver.lib.types import EditHistoryEvent
@ -72,22 +70,6 @@ DB_TOPIC_NAME = "subject"
MESSAGE__TOPIC = "message__subject" MESSAGE__TOPIC = "message__subject"
def topic_match_sa(topic_name: str) -> ColumnElement[Boolean]:
# _sa is short for SQLAlchemy, which we use mostly for
# queries that search messages
topic_cond = func.upper(column("subject", Text)) == func.upper(literal(topic_name))
return topic_cond
def get_resolved_topic_condition_sa() -> ColumnElement[Boolean]:
resolved_topic_cond = column("subject", Text).startswith(RESOLVED_TOPIC_PREFIX)
return resolved_topic_cond
def topic_column_sa() -> ColumnElement[Text]:
return column("subject", Text)
def filter_by_topic_name_via_message( def filter_by_topic_name_via_message(
query: QuerySet[UserMessage], topic_name: str query: QuerySet[UserMessage], topic_name: str
) -> QuerySet[UserMessage]: ) -> QuerySet[UserMessage]:

View File

@ -0,0 +1,20 @@
from sqlalchemy.sql import ColumnElement, column, func, literal
from sqlalchemy.types import Boolean, Text
from zerver.lib.topic import RESOLVED_TOPIC_PREFIX
def topic_match_sa(topic_name: str) -> ColumnElement[Boolean]:
# _sa is short for SQLAlchemy, which we use mostly for
# queries that search messages
topic_cond = func.upper(column("subject", Text)) == func.upper(literal(topic_name))
return topic_cond
def get_resolved_topic_condition_sa() -> ColumnElement[Boolean]:
resolved_topic_cond = column("subject", Text).startswith(RESOLVED_TOPIC_PREFIX)
return resolved_topic_cond
def topic_column_sa() -> ColumnElement[Text]:
return column("subject", Text)

View File

@ -10,7 +10,7 @@ from sqlalchemy.sql import ClauseElement, and_, column, not_, or_
from sqlalchemy.types import Integer from sqlalchemy.types import Integer
from zerver.lib.timestamp import datetime_to_timestamp from zerver.lib.timestamp import datetime_to_timestamp
from zerver.lib.topic import topic_match_sa from zerver.lib.topic_sqlalchemy import topic_match_sa
from zerver.lib.types import UserTopicDict from zerver.lib.types import UserTopicDict
from zerver.models import UserProfile, UserTopic from zerver.models import UserProfile, UserTopic
from zerver.models.streams import get_stream from zerver.models.streams import get_stream

View File

@ -24,7 +24,8 @@ from zerver.lib.narrow import (
from zerver.lib.request import REQ, RequestNotes, has_request_variables from zerver.lib.request import REQ, RequestNotes, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.sqlalchemy_utils import get_sqlalchemy_connection from zerver.lib.sqlalchemy_utils import get_sqlalchemy_connection
from zerver.lib.topic import DB_TOPIC_NAME, MATCH_TOPIC, topic_column_sa from zerver.lib.topic import DB_TOPIC_NAME, MATCH_TOPIC
from zerver.lib.topic_sqlalchemy import topic_column_sa
from zerver.lib.validator import check_bool, check_int, check_list, to_non_negative_int from zerver.lib.validator import check_bool, check_int, check_list, to_non_negative_int
from zerver.models import UserMessage, UserProfile from zerver.models import UserMessage, UserProfile