Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
record_queries.py118 linesDownload Raw Back to flask_sqlalchemy
1from __future__ import annotations2 3import dataclasses4import inspect5import typing as t6from time import perf_counter7 8import sqlalchemy as sa9import sqlalchemy.event as sa_event10from flask import current_app11from flask import g12from flask import has_app_context13 14 15def get_recorded_queries() -> list[_QueryInfo]:16    """Get the list of recorded query information for the current session. Queries are17    recorded if the config :data:`.SQLALCHEMY_RECORD_QUERIES` is enabled.18 19    Each query info object has the following attributes:20 21    ``statement``22        The string of SQL generated by SQLAlchemy with parameter placeholders.23    ``parameters``24        The parameters sent with the SQL statement.25    ``start_time`` / ``end_time``26        Timing info about when the query started execution and when the results where27        returned. Accuracy and value depends on the operating system.28    ``duration``29        The time the query took in seconds.30    ``location``31        A string description of where in your application code the query was executed.32        This may not be possible to calculate, and the format is not stable.33 34    .. versionchanged:: 3.035        Renamed from ``get_debug_queries``.36 37    .. versionchanged:: 3.038        The info object is a dataclass instead of a tuple.39 40    .. versionchanged:: 3.041        The info object attribute ``context`` is renamed to ``location``.42 43    .. versionchanged:: 3.044        Not enabled automatically in debug or testing mode.45    """46    return g.get("_sqlalchemy_queries", [])  # type: ignore[no-any-return]47 48 49@dataclasses.dataclass50class _QueryInfo:51    """Information about an executed query. Returned by :func:`get_recorded_queries`.52 53    .. versionchanged:: 3.054        Renamed from ``_DebugQueryTuple``.55 56    .. versionchanged:: 3.057        Changed to a dataclass instead of a tuple.58 59    .. versionchanged:: 3.060        ``context`` is renamed to ``location``.61    """62 63    statement: str | None64    parameters: t.Any65    start_time: float66    end_time: float67    location: str68 69    @property70    def duration(self) -> float:71        return self.end_time - self.start_time72 73 74def _listen(engine: sa.engine.Engine) -> None:75    sa_event.listen(engine, "before_cursor_execute", _record_start, named=True)76    sa_event.listen(engine, "after_cursor_execute", _record_end, named=True)77 78 79def _record_start(context: sa.engine.ExecutionContext, **kwargs: t.Any) -> None:80    if not has_app_context():81        return82 83    context._fsa_start_time = perf_counter()  # type: ignore[attr-defined]84 85 86def _record_end(context: sa.engine.ExecutionContext, **kwargs: t.Any) -> None:87    if not has_app_context():88        return89 90    if "_sqlalchemy_queries" not in g:91        g._sqlalchemy_queries = []92 93    import_top = current_app.import_name.partition(".")[0]94    import_dot = f"{import_top}."95    frame = inspect.currentframe()96 97    while frame:98        name = frame.f_globals.get("__name__")99 100        if name and (name == import_top or name.startswith(import_dot)):101            code = frame.f_code102            location = f"{code.co_filename}:{frame.f_lineno} ({code.co_name})"103            break104 105        frame = frame.f_back106    else:107        location = "<unknown>"108 109    g._sqlalchemy_queries.append(110        _QueryInfo(111            statement=context.statement,112            parameters=context.parameters,113            start_time=context._fsa_start_time,  # type: ignore[attr-defined]114            end_time=perf_counter(),115            location=location,116        )117    )118 
codekingpro/portable-devtools · Team Ai