psycodict.searchtable¶
The read half of a table: dictionary queries.
PostgresSearchTable extends
PostgresTable with the query API – search,
lucky, lookup, count, random and friends – translating
query dictionaries into SQL SELECT statements, with projections, sorting,
joins and the info contract used by search pages. The query language
is specified in QueryLanguage.md and the read API in Searching.md.
- class psycodict.searchtable.PostgresSearchTable(db, search_table, label_col, sort=None, count_cutoff=1000, id_ordered=False, out_of_order=False, stats_valid=True, total=None, include_nones=True, data_types=None)[source]¶
Bases:
PostgresTableA single search table, as returned by
db.<tablename>: the interface for reading data with dictionary queries.The read methods –
search(),lucky(),lookup(),exists(),count(),random(),distinct()and friends – accept a query dictionary such as{"degree": 2, "disc": {"$lt": 0}}, translate it into SQL, and return rows as dictionaries (or bare values, under a string projection). The query language is specified in QueryLanguage.md and the read API in Searching.md. Writing and schema changes live on the base classPostgresTable, and precomputed statistics onPostgresStatsTable(available asself.stats).Instances are constructed by
PostgresDatabasefrom each table’smeta_tablesrow; they are not meant to be created directly.- lucky(query={}, projection=2, offset=0, sort=[], raw=None, raw_values=None, join=None)[source]¶
One of the two main public interfaces for performing SELECT queries, intended for situations where only a single result is desired.
INPUT:
query– a mongo-style dictionary specifying the query. Generally, the keys will correspond to columns, and values will either be specific numbers (specifying an equality test) or dictionaries giving more complicated constraints. The main exception is that “$or” can be a top level key, specifying a list of constraints of which at least one must be true.projection– which columns are desired. This can be specified either as a list of columns to include; a dictionary specifying columns to include (using all True values) or exclude (using all False values); a string giving a single column (only returns the value, not a dictionary); or an integer code (0 means only return the label, 1 means return all search columns, 2 means all columns (default)).offset– integer. allows retrieval of a later record rather than just first.sort– The sort order, from which the first result is returned.None, Using the default sort order for the table
a list of strings (which are interpreted as column names in the ascending direction) or of pairs (column name, 1 or -1). If not specified, will use the default sort order on the table.
[] (default), unsorted, thus if there is more than one match to the query then the choice of the result is arbitrary.
raw– a string, to be used as the WHERE part of the query. DO NOT USE THIS DIRECTLY FOR INPUT FROM WEBSITE.raw_values– a list of values to be substituted for %s entries in the raw string. Useful when strings might include quotes.join– a list of tuples describing other search tables to join to this one, as forsearch. Not compatible withraw.
OUTPUT:
If projection is 0 or a string, returns the label/column value of the first record satisfying the query. Otherwise, return a dictionary with keys the column names requested by the projection.
EXAMPLES:
sage: from lmfdb import db sage: nf = db.nf_fields sage: nf.lucky({'degree':int(2),'disc_sign':int(1),'disc_abs':int(5)},projection=0) '2.2.5.1' sage: nf.lucky({'label':'6.6.409587233.1'},projection=1) {'class_group': [], 'class_number': 1, 'cm': False, 'coeffs': [2, -31, 30, 11, -13, -1, 1], 'degree': 6, 'disc_abs': 409587233, 'disc_rad': 409587233, 'disc_sign': 1, 'galt': 16, 'label': '6.6.409587233.1', 'oldpolredabscoeffs': None, 'r2': 0, 'ramps': [11, 53, 702551], 'used_grh': False} sage: nf.lucky({'label':'6.6.409587233.1'},projection=['regulator']) {'regulator':455.191694993}
- search(query={}, projection=1, limit=None, offset=0, sort=None, info=None, split_ors=False, one_per=None, silent=False, raw=None, raw_values=None, join=None)[source]¶
One of the two main public interfaces for performing SELECT queries, intended for usage from search pages where multiple results may be returned.
INPUT:
query– a mongo-style dictionary specifying the query. Generally, the keys will correspond to columns, and values will either be specific numbers (specifying an equality test) or dictionaries giving more complicated constraints. The main exception is that “$or” can be a top level key, specifying a list of constraints of which at least one must be true.projection– which columns are desired. This can be specified either as a list of columns to include; a dictionary specifying columns to include (using all True values) or exclude (using all False values); a string giving a single column (only returns the value, not a dictionary); or an integer code (0 means only return the label, 1 means return all search columns (default), 2 means all columns).limit– an integer or None (default), giving the maximum number of records to return.offset– a nonnegative integer (default 0), where to start in the list of results.sort– a sort order. Either None or a list of strings (which are interpreted as column names in the ascending direction) or of pairs (column name, 1 or -1). If not specified, will use the default sort order on the table. If you want the result unsorted, use [].info– a dictionary, which is updated with values of ‘query’, ‘count’, ‘start’, ‘exact_count’ and ‘number’. Optional.split_ors– a boolean. If true, executes one query per clause in the$orlist, combining the results. Only used when a limit is provided.one_per– a list of columns. If provided, only one result will be included with each given set of values for those columns (the first according to the provided sort order).silent– a boolean. If True, slow query warnings will be suppressed.raw– a string, to be used as the WHERE part of the query. DO NOT USE THIS DIRECTLY FOR INPUT FROM WEBSITE.raw_values– a list of values to be substituted for %s entries in the raw string. Useful when strings might include quotes.join– a list of tuples(col1, col2)or(col1, col2, jointype)describing other search tables to join to this one. In each tuple,col2must be qualified as"table.column"and names the table being joined;col1is a column of this table, or of a previously joined table if qualified.jointypeis"inner"(the default),"left","right"or"full". Whenjoinis given, query keys, projection entries, sort entries,$colnames and names in$rawexpressions may be qualified as"table.column"to refer to columns of the joined tables (unqualified names refer to this table, with periods keeping their usual path meaning), and the keys in the result dictionaries match the projection entries as given. Counts are never cached, andsplit_ors,one_perandraware not supported. See the Joined queries section of QueryLanguage.md for details.
OUTPUT:
If
limitis None, returns an iterator over the results, yielding dictionaries with keys the columns requested by the projection (or labels/column values if the projection is 0 or a string)Otherwise, returns a list with the same data.
EXAMPLES:
sage: from lmfdb import db sage: nf = db.nf_fields sage: info = {} sage: nf.search({'degree':int(2),'class_number':int(1),'disc_sign':int(-1)}, projection=0, limit=4, info=info) ['2.0.3.1', '2.0.4.1', '2.0.7.1', '2.0.8.1'] sage: info['number'], info['exact_count'] (9, True) sage: info = {} sage: nf.search({'degree':int(6)}, projection=['label','class_number','galt'], limit=4, info=info) [{'class_number': 1, 'galt': 5, 'label': '6.0.9747.1'}, {'class_number': 1, 'galt': 11, 'label': '6.0.10051.1'}, {'class_number': 1, 'galt': 11, 'label': '6.0.10571.1'}, {'class_number': 1, 'galt': 5, 'label': '6.0.10816.1'}] sage: info['number'], info['exact_count'] (5522600, True) sage: info = {} sage: nf.search({'ramps':{'$contains':[int(2),int(7)]}}, limit=4, info=info) [{'label': '2.2.28.1', 'ramps': [2, 7]}, {'label': '2.0.56.1', 'ramps': [2, 7]}, {'label': '2.2.56.1', 'ramps': [2, 7]}, {'label': '2.0.84.1', 'ramps': [2, 3, 7]}] sage: info['number'], info['exact_count'] (1000, False)
Columns of other tables can be searched on and projected onto by joining the tables:
sage: db.ec_nfcurves.search( ....: {"rank": 1, "nf_fields.r2": 1}, ....: ["label", "nf_fields.degree"], ....: join=[("field_label", "nf_fields.label")], ....: limit=3) [{'label': '2.0.1003.1-9.1-c1', 'nf_fields.degree': 2}, {'label': '2.0.1003.1-9.1-c2', 'nf_fields.degree': 2}, {'label': '2.0.1003.1-9.1-d1', 'nf_fields.degree': 2}]
- lookup(label, projection=2, label_col=None, join=None)[source]¶
Look up a record by its label.
INPUT:
label– string, the label for the desired record.projection– which columns are requested (default 2, meaning all columns).See
_parse_projectionfor more details.
label_col– which column holds the label. Most tables store a default.join– a list of tuples describing other search tables to join to this one, as forsearch.
OUTPUT:
A dictionary with keys the column names requested by the projection.
Note, the example below uses loc_algebras which is no longer a column EXAMPLES:
sage: from lmfdb import db sage: nf = db.nf_fields sage: rec = nf.lookup('8.0.374187008.1') sage: rec['loc_algebras']['13'] 'x^2-13,x^2-x+2,x^4+x^2-x+2'
- exists(query)[source]¶
Determines whether there exists at least one record satisfying the query.
INPUT:
query– a mongo style dictionary specifying the search. Seesearchfor more details.
OUTPUT:
Boolean, whether there exists a record.
EXAMPLES:
sage: from lmfdb import db sage: nf = db.nf_fields sage: nf.exists({'class_number':int(7)}) True
- label_exists(label, label_col=None)[source]¶
Determines whether these exists a record with the given label.
INPUT:
label– a string, the labellabel_col– the column holding the label (most tables have a default setting)
- random(query={}, projection=0, pick_first=None)[source]¶
Return a random label or record from this table.
INPUT:
query– a query dictionary from which a result will be selected, uniformly at randomprojection– which columns are requested (default 0, meaning just the label). See_parse_projectionfor more details.pick_first– a column name. If provided, a value is chosen uniformly from the distinct values (subject to the given query), then a random element is chosen with that value. Note that the set of distinct values is computed and stored, so be careful not to choose a column that takes on too many values.
OUTPUT:
If projection is 0, a random label from the table. Otherwise, a dictionary with keys specified by the projection. A RuntimeError is raised if the selection fails when there are rows in the table; this can occur if the ids are not consecutive due to deletions. If there are no results satisfying the query, None is returned (analogously to the
luckymethod).EXAMPLES:
sage: from lmfdb import db sage: nf = db.nf_fields sage: nf.random() '2.0.294787.1'
- random_sample(ratio, query={}, projection=1, mode=None, repeatable=None, silent=False)[source]¶
Returns a random sample of rows from this table. Note that ratio is not guaranteed, and different modes will have different levels of randomness.
INPUT:
ratio– a float between 0 and 1, the approximate fraction of rows satisfying the query to be returned.query– a dictionary query, as for searching. Note that the WHERE clause is applied after the random selection except when using ‘choice’ modeprojection– a description of which columns to include in the search resultsmode– one of'system','bernoulli','choice'andNone: -system– the fastest option, but will introduce clustering since random pages are selected rather than random rows. -bernoulli– rows are selected independently with probability the given ratio, then the where clause is applied -choice– all results satisfying the query are fetched, then a random subset is chosen. This will be slow if a large number of rows satisfy the query, but performs much better when only a few rows satisfy the query. This option matches ratio mostly accurately. -None– Usesbernoulliif more thanself._count_cutoffresults satisfy the query, otherwise useschoice.repeatable– an integer, giving a random seed for a repeatable result.silent– whether to suppress slow query warnings
- copy_to_example(searchfile, id=None, sep='|')[source]¶
This function writes files in the format used for copy_from and reload. It writes the header and a single random row.
INPUT:
searchfile– a string, the filename to write data into for the search tableid– an id to use for the example row (random if unspecified)sep– a character to use as a separator between columns
- max(col, constraint={})[source]¶
The maximum value attained by the given column.
INPUT:
col– the name of the columnconstraint– a query dictionary constraining which rows are considered
EXAMPLES:
sage: from lmfdb import db sage: db.nf_fields.max('class_number') 1892503075117056
- min(col, constraint={})[source]¶
The minimum value attained by the given column.
INPUT:
col– the name of the columnconstraint– a query dictionary constraining which rows are considered
EXAMPLES:
sage: from lmfdb import db sage: db.ec_mwbsd.min('area') 0.00000013296713869846309987200099760
- distinct(col, query={})[source]¶
Returns a list of the distinct values taken on by a given column.
INPUT:
col– the name of the columnquery– a query dictionary constraining which rows are considered
- count(query={}, groupby=None, record=False, join=None)[source]¶
Count the number of results for a given query.
INPUT:
query– a mongo-style dictionary, as in thesearchmethod.groupby– (default None) a list of columnsrecord– (default False) whether to record the number of results in the counts table. Recording is useful for queries whose counts are displayed repeatedly (search pages record theirs), but every distinct recorded query adds a row to the counts table, so it is opt-in: scripts running many one-off counts no longer clutter the table (and slow down reloads) by accident. Recording also requiressavingto be enabled on the stats table; with the psycodict defaultsaving = Falsenothing is written.join– a list of tuples describing other search tables to join to this one, as forsearch. Counts of joined queries are computed directly and never cached, sorecordis ignored;groupbyis not supported withjoin.
OUTPUT:
If
groupbyis None, the number of records satisfying the query. Otherwise, a dictionary with keys the distinct tuples of values taken on by the columns ingroupby, and values the number of rows with those values.EXAMPLES:
sage: from lmfdb import db sage: nf = db.nf_fields sage: nf.count({'degree':int(6),'galt':int(7)}) 244006
- count_distinct(col, query={}, record=False)[source]¶
Count the number of distinct values taken on by a given column.
The result will be the same as taking the length of the distinct values, but a bit faster and can cache the answer
INPUT:
col– the name of the column, or a list of such namesquery– a query dictionary constraining which rows are consideredrecord– (default False) whether to record the number of results in the stats table; opt-in for the same reason as incount.