psycodict.utils¶
Helpers shared across psycodict: DelayCommit for batching many
writes into one transaction, the whitelist parser that admits limited raw
arithmetic into queries (filter_sql_injection()), identifier wrapping
with array slicers (IdentifierWrapper()), the exceptions raised during
query parsing and locking, and small formatting utilities.
- exception psycodict.utils.SearchParsingError(*args, **kwargs)[source]¶
Bases:
ValueErrorUsed for errors raised when parsing search boxes
- psycodict.utils.filter_sql_injection(clause, col, col_type, op, table, join_context=None)[source]¶
Build a comparison clause from an untrusted arithmetic expression, admitting only whitelisted column names, numbers and the arithmetic operators
+-*/^(). Returns a pair of an SQL composable and the list of values to substitute into it.INPUT:
clause– a plain string, obtained from the website UI so NOT SAFEcol– an SQL Identifier for a column in a tablecol_type– a string giving the type of the columnop– a string giving the operator to use (=or one of the values in thepostgres_infix_opsdictionary above)table– a PostgresTable object for determining which columns are validjoin_context– when filtering an expression inside a joined query, a dictionary mapping joined table names to their table objects. Names then resolve like query keys – bare names are columns oftable, while “joinedtable.column” names a joined table’s column – and every identifier is emitted table-qualified.
- psycodict.utils.IdentifierWrapper(name, convert=True)[source]¶
Returns a composable representing an SQL identifier.
This is wrapper for psycopg.sql.Identifier that supports ARRAY slicers and converts them (if desired) from the Python format to SQL, as SQL starts at 1, and it is inclusive at the end
EXAMPLES:
sage: IdentifierWrapper('name') Identifier('name') sage: print(IdentifierWrapper('name[:10]').as_string(db.conn)) "name"[:10] sage: print(IdentifierWrapper('name[1:10]').as_string(db.conn)) "name"[2:10] sage: print(IdentifierWrapper('name[1:10]', convert = False).as_string(db.conn)) "name"[1:10] sage: print(IdentifierWrapper('name[1:10:3]').as_string(db.conn)) "name"[2:10:3] sage: print(IdentifierWrapper('name[1:10:3][0:2]').as_string(db.conn)) "name"[2:10:3][1:2] sage: print(IdentifierWrapper('name[1:10:3][0::1]').as_string(db.conn)) "name"[2:10:3][1::1] sage: print(IdentifierWrapper('name[1:10:3][0]').as_string(db.conn)) "name"[2:10:3][1]
- exception psycodict.utils.LockError[source]¶
Bases:
RuntimeErrorRaised when a data-changing operation cannot proceed because another operation holds a conflicting lock on the table (for example, a reload in progress, or a staged
_tmpcopy awaiting its swap).
- class psycodict.utils.QueryLogFilter[source]¶
Bases:
objectA filter used when logging slow queries.
- class psycodict.utils.DelayCommit(obj, final_commit=True, silence=None, active=True)[source]¶
Bases:
objectUsed to set default behavior for whether to commit changes to the database connection.
Entering this context in a with statement will cause
_executecalls to not commit by default. When the final DelayCommit is exited, the connection will commit.Setting active=False disables the DelayCommit completely, which can be helpful since it’s often used in a with context and conditionally entering that context is annoying to write with if statements.
- psycodict.utils.reraise(exc_type, exc_value, exc_traceback=None)[source]¶
Reraise an exception, possibly with a different message, type, or traceback.
- psycodict.utils.range_formatter(x)[source]¶
Format a query-language range constraint for human display:
{"$gte": 2, "$lte": 7}becomes"2-7", one-sided constraints become"2-"or"..7", andNonebecomes"Unknown".
- class psycodict.utils.KeyedDefaultDict[source]¶
Bases:
defaultdictA defaultdict where the default value takes the key as input.