Module pyracmon.context
This module provides the context type which controls query execution as configured.
Expand source code
"""
This module provides the context type which controls query execution as configured.
"""
from collections.abc import Sequence
import logging
from typing import Any, Union, Optional, Literal, overload
try:
from typing import TypeAlias
except:
from typing_extensions import TypeAlias
from .config import default_config
from . import dbapi
PARAMS: TypeAlias = Union[list[Any], dict[str, Any]]
"""Type alias of parameters of query.
Which type in `list` or `dict` is used depends on the type of the marker.
"""
class ConnectionContext:
"""
This class represents a context of query execution.
By default, the context based on global configuration is used.
You should declare your own context class and set it to `Connection.use` if you want to change the behavior.
Custom context is also useful to change cursor state before and after query execution. Overwrite `execute` method to do it.
"""
def __init__(self, identifier: Optional[str] = None, **configurations):
#: Identifier of this context. `None` by default.
self.identifier = identifier
#: Configuration used in this context.
self.config = default_config().derive(**configurations)
def _message(self, message):
return f"({self.identifier}) {message}" if self.identifier else message
def configure(self, **configurations: Any) -> 'ConnectionContext':
"""
Change configurations of this context.
Changes by this method never affect global configuration even if the context is based on it.
Args:
configurations: Configurations. See `pyracmon.config` to know available keys.
Returns:
This instance.
"""
self.config.set(**configurations)
return self
def execute(self, cursor: dbapi.Cursor, sql: str, params: PARAMS) -> dbapi.Cursor:
"""
Executes a query on a cursor.
Args:
cursor: Cursor object.
sql: Query string.
params: Query parameters.
Returns:
Given cursor object. Internal state may be changed by the execution of the query.
"""
return self._execute(cursor, sql, params, False)
def executemany(self, cursor: dbapi.Cursor, sql: str, seq_of_params: Sequence[PARAMS]) -> dbapi.Cursor:
"""
Repeats query on a cursor for sequencee of parameters.
This method works similar to `execute` but invoke `executemany` instead.
Args:
cursor: Cursor object.
sql: Query string.
seq_of_args: A sequence of parameters of the query.
Returns:
Given cursor object. Internal state may be changed by the execution of the query.
"""
return self._execute(cursor, sql, seq_of_params, True)
@overload
def _execute(self, cursor: dbapi.Cursor, sql: str, params: PARAMS, is_many: Literal[False] = False) -> dbapi.Cursor: ...
@overload
def _execute(self, cursor: dbapi.Cursor, sql: str, params: Sequence[PARAMS], is_many: Literal[True] = True) -> dbapi.Cursor: ...
def _execute(
self,
cursor: dbapi.Cursor,
sql: str,
params,
is_many: bool = False,
) -> dbapi.Cursor:
logger = _logger(self.config)
if logger:
sql_log = sql if len(sql) <= self.config.sql_log_length else f"{sql[0:self.config.sql_log_length]}..."
logger.log(self.config.log_level, self._message(sql_log))
if self.config.parameter_log:
if is_many:
for ps in params:
logger.log(self.config.log_level, self._message(f"Parameters: {ps}"))
else:
logger.log(self.config.log_level, self._message(f"Parameters: {params}"))
if is_many:
cursor.executemany(sql, params)
else:
cursor.execute(sql, params)
return cursor
def _logger(config):
if isinstance(config.logger, logging.Logger):
return config.logger
elif isinstance(config.logger, str):
return logging.getLogger(config.logger)
else:
return None
Global variables
var PARAMS : TypeAlias
-
Type alias of parameters of query.
Which type in
list
ordict
is used depends on the type of the marker.
Classes
class ConnectionContext (identifier: Optional[str] = None, **configurations)
-
This class represents a context of query execution.
By default, the context based on global configuration is used. You should declare your own context class and set it to
Connection.use
if you want to change the behavior.Custom context is also useful to change cursor state before and after query execution. Overwrite
execute
method to do it.Expand source code
class ConnectionContext: """ This class represents a context of query execution. By default, the context based on global configuration is used. You should declare your own context class and set it to `Connection.use` if you want to change the behavior. Custom context is also useful to change cursor state before and after query execution. Overwrite `execute` method to do it. """ def __init__(self, identifier: Optional[str] = None, **configurations): #: Identifier of this context. `None` by default. self.identifier = identifier #: Configuration used in this context. self.config = default_config().derive(**configurations) def _message(self, message): return f"({self.identifier}) {message}" if self.identifier else message def configure(self, **configurations: Any) -> 'ConnectionContext': """ Change configurations of this context. Changes by this method never affect global configuration even if the context is based on it. Args: configurations: Configurations. See `pyracmon.config` to know available keys. Returns: This instance. """ self.config.set(**configurations) return self def execute(self, cursor: dbapi.Cursor, sql: str, params: PARAMS) -> dbapi.Cursor: """ Executes a query on a cursor. Args: cursor: Cursor object. sql: Query string. params: Query parameters. Returns: Given cursor object. Internal state may be changed by the execution of the query. """ return self._execute(cursor, sql, params, False) def executemany(self, cursor: dbapi.Cursor, sql: str, seq_of_params: Sequence[PARAMS]) -> dbapi.Cursor: """ Repeats query on a cursor for sequencee of parameters. This method works similar to `execute` but invoke `executemany` instead. Args: cursor: Cursor object. sql: Query string. seq_of_args: A sequence of parameters of the query. Returns: Given cursor object. Internal state may be changed by the execution of the query. """ return self._execute(cursor, sql, seq_of_params, True) @overload def _execute(self, cursor: dbapi.Cursor, sql: str, params: PARAMS, is_many: Literal[False] = False) -> dbapi.Cursor: ... @overload def _execute(self, cursor: dbapi.Cursor, sql: str, params: Sequence[PARAMS], is_many: Literal[True] = True) -> dbapi.Cursor: ... def _execute( self, cursor: dbapi.Cursor, sql: str, params, is_many: bool = False, ) -> dbapi.Cursor: logger = _logger(self.config) if logger: sql_log = sql if len(sql) <= self.config.sql_log_length else f"{sql[0:self.config.sql_log_length]}..." logger.log(self.config.log_level, self._message(sql_log)) if self.config.parameter_log: if is_many: for ps in params: logger.log(self.config.log_level, self._message(f"Parameters: {ps}")) else: logger.log(self.config.log_level, self._message(f"Parameters: {params}")) if is_many: cursor.executemany(sql, params) else: cursor.execute(sql, params) return cursor
Instance variables
var config
-
Configuration used in this context.
var identifier
-
Identifier of this context.
None
by default.
Methods
def configure(self, **configurations: Any) ‑> ConnectionContext
-
Change configurations of this context.
Changes by this method never affect global configuration even if the context is based on it.
Args
configurations
- Configurations. See
pyracmon.config
to know available keys.
Returns
This instance.
Expand source code
def configure(self, **configurations: Any) -> 'ConnectionContext': """ Change configurations of this context. Changes by this method never affect global configuration even if the context is based on it. Args: configurations: Configurations. See `pyracmon.config` to know available keys. Returns: This instance. """ self.config.set(**configurations) return self
def execute(self, cursor: Cursor, sql: str, params: Union[list[Any], dict[str, Any]]) ‑> Cursor
-
Executes a query on a cursor.
Args
cursor
- Cursor object.
sql
- Query string.
params
- Query parameters.
Returns
Given cursor object. Internal state may be changed by the execution of the query.
Expand source code
def execute(self, cursor: dbapi.Cursor, sql: str, params: PARAMS) -> dbapi.Cursor: """ Executes a query on a cursor. Args: cursor: Cursor object. sql: Query string. params: Query parameters. Returns: Given cursor object. Internal state may be changed by the execution of the query. """ return self._execute(cursor, sql, params, False)
def executemany(self, cursor: Cursor, sql: str, seq_of_params: collections.abc.Sequence[typing.Union[list[typing.Any], dict[str, typing.Any]]]) ‑> Cursor
-
Repeats query on a cursor for sequencee of parameters.
This method works similar to
execute
but invokeexecutemany
instead.Args
cursor
- Cursor object.
sql
- Query string.
seq_of_args
- A sequence of parameters of the query.
Returns
Given cursor object. Internal state may be changed by the execution of the query.
Expand source code
def executemany(self, cursor: dbapi.Cursor, sql: str, seq_of_params: Sequence[PARAMS]) -> dbapi.Cursor: """ Repeats query on a cursor for sequencee of parameters. This method works similar to `execute` but invoke `executemany` instead. Args: cursor: Cursor object. sql: Query string. seq_of_args: A sequence of parameters of the query. Returns: Given cursor object. Internal state may be changed by the execution of the query. """ return self._execute(cursor, sql, seq_of_params, True)