Query-builder
- query = MyModel.select()
- new_query = query.where(MyModel.field == 'value')
unwrap
()API for recursively unwrapping “wrapped” nodes. Base case is toreturn self.
- API for determining if a node, at any point, has been explicitlyaliased by the user.
- class
Source
([alias=None]) - A source of row tuples, for example a table, join, or select query. Bydefault provides a “magic” attribute named “c” that is a factory forcolumn/attribute lookups, for example:
- User = Table('users')
- query = (User
- .select(User.c.username)
- .where(User.c.active == True)
- .order_by(User.c.username))
Parameters:columns – Column
instances, expressions, functions,sub-queries, or anything else that you would like to select.
Create a Select
query on the table. If the table explicitlydeclares columns and no columns are provided, then by default all thetable’s defined columns will be selected.
Parameters:
- **dest** ([_Source_](#Source)) – Join the table with the given destination.
- **join_type** (_str_) – Join type.
- **on** – Expression to use as join predicate.Returns:
a Join
instance.
Join type may be one of:
- <code>JOIN.INNER</code>
- <code>JOIN.LEFT_OUTER</code>
- <code>JOIN.RIGHT_OUTER</code>
- <code>JOIN.FULL</code>
- <code>JOIN.FULL_OUTER</code>
- <code>JOIN.CROSS</code>
Parameters:
- **dest** ([_Source_](#Source)) – Join the table with the given destination.
- **on** – Expression to use as join predicate.Returns:
a Join
instance.
Convenience method for calling join()
using a LEFTOUTER join.
- class
Table
(name[, columns=None[, primary_key=None[, schema=None[, alias=None]]]]) - Represents a table in the database (or a table-like object such as a view).
Parameters:
- name (str) – Database table name
- columns (tuple) – List of column names (optional).
- primary_key (str) – Name of primary key column.
- schema (str) – Schema name used to access table (if necessary).
- alias (str) – Alias to use for table in SQL queries.
Note
If columns are specified, the magic “c” attribute will be disabled.
When columns are not explicitly defined, tables have a special attribute“c” which is a factory that provides access to table columns dynamically.
Example:
- User = Table('users')
- query = (User
- .select(User.c.id, User.c.username)
- .order_by(User.c.username))
Equivalent example when columns are specified:
- User = Table('users', ('id', 'username'))
- query = (User
- .select(User.id, User.username)
- .order_by(User.username))
Parameters:database – Database
object.
Bind this table to the given database (or unbind by leaving empty).
When a table is bound to a database, queries may be executed againstit without the need to specify the database in the query’s executemethod.
Parameters:database – Database
object.
Return a context manager that will bind the table to the given databasefor the duration of the wrapped block.
Parameters:columns – Column
instances, expressions, functions,sub-queries, or anything else that you would like to select.
Create a Select
query on the table. If the table explicitlydeclares columns and no columns are provided, then by default all thetable’s defined columns will be selected.
Example:
- User = Table('users', ('id', 'username'))
- # Because columns were defined on the Table, we will default to
- # selecting both of the User table's columns.
- # Evaluates to SELECT id, username FROM users
- query = User.select()
- Note = Table('notes')
- query = (Note
- .select(Note.c.content, Note.c.timestamp, User.username)
- .join(User, on=(Note.c.user_id == User.id))
- .where(Note.c.is_published == True)
- .order_by(Note.c.timestamp.desc()))
- # Using a function to select users and the number of notes they
- # have authored.
- query = (User
- .select(
- User.username,
- fn.COUNT(Note.c.id).alias('n_notes'))
- .join(
- Note,
- JOIN.LEFT_OUTER,
- on=(User.id == Note.c.user_id))
- .order_by(fn.COUNT(Note.c.id).desc()))
Parameters:
- **insert** – A dictionary mapping column to value, an iterable thatyields dictionaries (i.e. list), or a [<code>Select</code>](#Select) query.
- **columns** (_list_) – The list of columns to insert into when thedata being inserted is not a dictionary.
- **kwargs** – Mapping of column-name to value.
Create a Insert
query into the table.
Parameters:
- **insert** – A dictionary mapping column to value, an iterable thatyields dictionaries (i.e. list), or a [<code>Select</code>](#Select) query.
- **columns** (_list_) – The list of columns to insert into when thedata being inserted is not a dictionary.
- **kwargs** – Mapping of column-name to value.
Create a Insert
query into the table whose conflictresolution method is to replace.
Parameters:
- **update** – A dictionary mapping column to value.
- **kwargs** – Mapping of column-name to value.
Create a Update
query for the table.
delete
()- Create a
Delete
query for the table.
- class
Join
(lhs, rhs[, join_type=JOIN.INNER[, on=None[, alias=None]]]) - Represent a JOIN between to table-like objects.
Parameters:
- lhs – Left-hand side of the join.
- rhs – Right-hand side of the join.
- join_type – Type of join. e.g. JOIN.INNER, JOIN.LEFT_OUTER, etc.
- on – Expression describing the join predicate.
- alias (str) – Alias to apply to joined data.
Parameters:predicate (Expression) – join predicate.
Specify the predicate expression used for this join.
- class
ValuesList
(values[, columns=None[, alias=None]]) - Represent a values list that can be used like a table.
Parameters:
- values – a list-of-lists containing the row data to represent.
- columns (list) – the names to give to the columns in each row.
- alias (str) – alias to use for values-list.
Example:
- data = [(1, 'first'), (2, 'second')]
- vl = ValuesList(data, columns=('idx', 'name'))
- query = (vl
- .select(vl.c.idx, vl.c.name)
- .order_by(vl.c.idx))
- # Yields:
- # SELECT t1.idx, t1.name
- # FROM (VALUES (1, 'first'), (2, 'second')) AS t1(idx, name)
- # ORDER BY t1.idx
Parameters:names – names to apply to the columns of data.
Example:
- vl = ValuesList([(1, 'first'), (2, 'second')])
- vl = vl.columns('idx', 'name').alias('v')
- query = vl.select(vl.c.idx, vl.c.name)
- # Yields:
- # SELECT v.idx, v.name
- # FROM (VALUES (1, 'first'), (2, 'second')) AS v(idx, name)
- class
CTE
(name, query[, recursive=False[, columns=None]]) - Represent a common-table-expression. For example queries, see Common Table Expressions.
Parameters:
- name – Name for the CTE.
- query –
Select
query describing CTE. - recursive (bool) – Whether the CTE is recursive.
- columns (list) – Explicit list of columns produced by CTE (optional).
selectfrom
(*columns_)- Create a SELECT query that utilizes the given common table expressionas the source for a new query.
Parameters:columns – One or more columns to select from the CTE.Returns:Select
query utilizing the common table expression
Parameters:other – recursive term, generally a Select
query.Returns:a recursive CTE
with the given recursive term.
Column-like objects can be composed using various operators and specialmethods.
&
: Logical AND|
: Logical OR+
: Addition-
: Subtraction*
: Multiplication/
: Division^
: Exclusive-OR==
: Equality!=
: Inequality>
: Greater-than<
: Less-than>=
: Greater-than or equal<=
: Less-than or equal<<
:IN
>>
:IS
(i.e.IS NULL
)%
:LIKE
**
:ILIKE
bin_and()
: Binary ANDbin_or()
: Binary ORin_()
:IN
not_in()
:NOT IN
regexp()
:REGEXP
is_null(True/False)
:IS NULL
orIS NOT NULL
contains(s)
:LIKE %s%
startswith(s)
:LIKE s%
endswith(s)
:LIKE %s
between(low, high)
:BETWEEN low AND high
concat()
:||
alias
(alias)
Parameters:alias (str) – Alias for the given column-like object.Returns:a Alias
object.
Indicate the alias that should be given to the specified column-likeobject.
Parameters:as_type (str) – Type name to cast to.Returns:a Cast
object.
Create a CAST
expression.
Parameters:
- **collation** (_str_) – Collation name to use for sorting.
- **nulls** (_str_) – Sort nulls (FIRST or LAST).Returns:
an ascending Ordering
object for the column.
Parameters:
- **collation** (_str_) – Collation name to use for sorting.
- **nulls** (_str_) – Sort nulls (FIRST or LAST).Returns:
an descending Ordering
object for the column.
Returns:a Negated
wrapper for the column.
Parameters:
- source (Source) – Source for column.
- name (str) – Column name.
Column on a table or a column returned by a sub-query.
Parameters:
- node (Node) – a column-like object.
- alias (str) – alias to assign to column.
Create a named alias for the given column-like object.
Parameters:alias (str) – new name (or None) for aliased column.
Create a new Alias
for the aliased column-like object. Ifthe new alias is None
, then the original column-like object isreturned.
Parameters:
- value – Python object or scalar value.
- converter – Function used to convert value into type the databaseunderstands.
- unpack (bool) – Whether lists or tuples should be unpacked into a listof values or treated as-is.
Value to be used in a parameterized query. It is the responsibility of thecaller to ensure that the value passed in can be adapted to a type thedatabase driver understands.
AsIs
(value)- Represents a
Value
that is treated as-is, and passed directlyback to the database driver. This may be useful if you are using databaseextensions that accept native Python data-types and you do not wish Peeweeto impose any handling of the values.
Parameters:
- node – A column-like object.
- cast (str) – Type to cast to.
Represents a CAST(<node> AS <cast>)
expression.
Parameters:
- node – A column-like object.
- direction (str) – ASC or DESC
- collation (str) – Collation name to use for sorting.
- nulls (str) – Sort nulls (FIRST or LAST).
Represent ordering by a column-like object.
Postgresql supports a non-standard clause (“NULLS FIRST/LAST”). Peewee willautomatically use an equivalent CASE
statement for databases that donot support this (Sqlite / MySQL).
Parameters:collation (str) – Collation name to use for sorting.
Asc
(node[, collation=None[, nulls=None]])- Short-hand for instantiating an ascending
Ordering
object.
Desc
(node[, collation=None[, nulls=None]])- Short-hand for instantiating an descending
Ordering
object.
Parameters:
- lhs – Left-hand side.
- op – Operation.
- rhs – Right-hand side.
- flat (bool) – Whether to wrap expression in parentheses.
Represent a binary expression of the form (lhs op rhs), e.g. (foo + 1).
Parameters:path – Components that make up the dotted-path of the entity name.
Represent a quoted entity in a query, such as a table, column, alias. Thename may consist of multiple components, e.g. “a_table”.”column_name”.
Parameters:
- sql (str) – SQL query string.
- params (tuple) – Parameters for query (optional).
Represent a parameterized SQL query or query-fragment.
Parameters:constraint (str) – Constraint SQL.
Represent a CHECK constraint.
Parameters:
- name (str) – Function name.
- arguments (tuple) – Arguments to function.
- coerce (bool) – Whether to coerce the function result to a particulardata-type when reading function return values from the cursor.
- python_value (callable) – Function to use for converting the returnvalue from the cursor.
Represent an arbitrary SQL function call.
Note
Rather than instantiating this class directly, it is recommended to usethe fn
helper.
Example of using fn
to call an arbitrary SQL function:
- # Query users and count of tweets authored.
- query = (User
- .select(User.username, fn.COUNT(Tweet.id).alias('ct'))
- .join(Tweet, JOIN.LEFT_OUTER, on=(User.id == Tweet.user_id))
- .group_by(User.username)
- .order_by(fn.COUNT(Tweet.id).desc()))
Parameters:
- **partition_by** (_list_) – List of columns to partition by.
- **order_by** (_list_) – List of columns / expressions to order window by.
- **start** – A [<code>SQL</code>](#SQL) instance or a string expressing thestart of the window range.
- **end** – A [<code>SQL</code>](#SQL) instance or a string expressing theend of the window range.
- **frame_type** (_str_) – <code>Window.RANGE</code>, <code>Window.ROWS</code> or<code>Window.GROUPS</code>.
- **window** ([_Window_](#Window)) – A [<code>Window</code>](#Window) instance.
- **exclude** – Frame exclusion, one of <code>Window.CURRENT_ROW</code>,<code>Window.GROUP</code>, <code>Window.TIES</code> or <code>Window.NO_OTHERS</code>.
Note
For an in-depth guide to using window functions with Peewee,see the Window functions section.
Examples:
- # Using a simple partition on a single column.
- query = (Sample
- .select(
- Sample.counter,
- Sample.value,
- fn.AVG(Sample.value).over([Sample.counter]))
- .order_by(Sample.counter))
- # Equivalent example Using a Window() instance instead.
- window = Window(partition_by=[Sample.counter])
- query = (Sample
- .select(
- Sample.counter,
- Sample.value,
- fn.AVG(Sample.value).over(window))
- .window(window) # Note call to ".window()"
- .order_by(Sample.counter))
- # Example using bounded window.
- query = (Sample
- .select(Sample.value,
- fn.SUM(Sample.value).over(
- partition_by=[Sample.counter],
- start=Window.CURRENT_ROW, # current row
- end=Window.following())) # unbounded following
- .order_by(Sample.id))
Parameters:where – Expression for filtering aggregate.
Add a FILTER (WHERE…)
clause to an aggregate function. The whereexpression is evaluated to determine which rows are fed to theaggregate function. This SQL feature is supported for Postgres andSQLite.
Parameters:coerce (bool) – Whether to attempt to coerce function-call resultto a Python data-type.
When coerce is True
, the target data-type is inferred using severalheuristics. Read the source for BaseModelCursorWrapper._initialize_columns
method to see how this works.
Parameters:python_value (callable) – Function to use for converting the returnvalue from the cursor.
Specify a particular function to use when converting values returned bythe database cursor. For example:
- # Get user and a list of their tweet IDs. The tweet IDs are
- # returned as a comma-separated string by the db, so we'll split
- # the result string and convert the values to python ints.
- tweet_ids = (fn
- .GROUP_CONCAT(Tweet.id)
- .python_value(lambda idlist: [int(i) for i in idlist]))
- query = (User
- .select(User.username, tweet_ids.alias('tweet_ids'))
- .group_by(User.username))
- for user in query:
- print(user.username, user.tweet_ids)
- # e.g.,
- # huey [1, 4, 5, 7]
- # mickey [2, 3, 6]
- # zaizee []
fn
()- The
fn()
helper is actually an instance ofFunction
that implements agetattr
hook to provide a nice API for callingSQL functions.
To create a node representative of a SQL function call, use the functionname as an attribute on fn
and then provide the arguments as you wouldif calling a Python function:
- # List users and the number of tweets they have authored,
- # from highest-to-lowest:
- sql_count = fn.COUNT(Tweet.id)
- query = (User
- .select(User, sql_count.alias('count'))
- .join(Tweet, JOIN.LEFT_OUTER)
- .group_by(User)
- .order_by(sql_count.desc()))
- # Get the timestamp of the most recent tweet:
- query = Tweet.select(fn.MAX(Tweet.timestamp))
- max_timestamp = query.scalar() # Retrieve scalar result from query.
Function calls can, like anything else, be composed and nested:
- # Get users whose username begins with "A" or "a":
- a_users = User.select().where(fn.LOWER(fn.SUBSTR(User.username, 1, 1)) == 'a')
- class
Window
([partition_by=None[, order_by=None[, start=None[, end=None[, frame_type=None[, extends=None[, exclude=None[, alias=None]]]]]]]])
Parameters:
- partition_by (list) – List of columns to partition by.
- order_by (list) – List of columns to order by.
- start – A
SQL
instance or a string expressing the startof the window range. - end – A
SQL
instance or a string expressing the end ofthe window range. - frame_type (str) –
Window.RANGE
,Window.ROWS
orWindow.GROUPS
. - extends – A
Window
definition to extend. Alternately, youmay specify the window’s alias instead. - exclude – Frame exclusion, one of
Window.CURRENT_ROW
,Window.GROUP
,Window.TIES
orWindow.NO_OTHERS
. - alias (str) – Alias for the window.
Represent a WINDOW clause.
Note
For an in-depth guide to using window functions with Peewee,see the Window functions section.
RANGE
ROWS
GROUPS
Specify the window
frame_type
. See Frame types: RANGE vs ROWS vs GROUPS.Reference to current row for use in start/end clause or the frameexclusion parameter.
GROUP
TIES
Specify the window frame exclusion parameter.
Parameters:value – Number of rows preceding. If None
is UNBOUNDED.
Convenience method for generating SQL suitable for passing in as thestart
parameter for a window range.
Parameters:value – Number of rows following. If None
is UNBOUNDED.
Convenience method for generating SQL suitable for passing in as theend
parameter for a window range.
Parameters:window (Window) – A Window
definition to extend.Alternately, you may specify the window’s alias instead.
Parameters:frame_exclusion – Frame exclusion, one of Window.CURRENT_ROW
,Window.GROUP
, Window.TIES
or Window.NO_OTHERS
.
Parameters:alias (str) – Alias to use for window.
Parameters:
- predicate – Predicate for CASE query (optional).
- expression_tuples – One or more cases to evaluate.
- default – Default value (optional).Returns:Representation of CASE statement.
Examples:
- Number = Table('numbers', ('val',))
- num_as_str = Case(Number.val, (
- (1, 'one'),
- (2, 'two'),
- (3, 'three')), 'a lot')
- query = Number.select(Number.val, num_as_str.alias('num_str'))
- # The above is equivalent to:
- # SELECT "val",
- # CASE "val"
- # WHEN 1 THEN 'one'
- # WHEN 2 THEN 'two'
- # WHEN 3 THEN 'three'
- # ELSE 'a lot' END AS "num_str"
- # FROM "numbers"
- num_as_str = Case(None, (
- (Number.val == 1, 'one'),
- (Number.val == 2, 'two'),
- (Number.val == 3, 'three')), 'a lot')
- query = Number.select(Number.val, num_as_str.alias('num_str'))
- # The above is equivalent to:
- # SELECT "val",
- # CASE
- # WHEN "val" = 1 THEN 'one'
- # WHEN "val" = 2 THEN 'two'
- # WHEN "val" = 3 THEN 'three'
- # ELSE 'a lot' END AS "num_str"
- # FROM "numbers"
Parameters:
- nodes (list) – Zero or more nodes.
- glue (str) – How to join the nodes when converting to SQL.
- parens (bool) – Whether to wrap the resulting SQL in parentheses.
Represent a list of nodes, a multi-part clause, a list of parameters, etc.
Parameters:nodes (list) – Zero or more nodes.Returns:a NodeList
Represent a list of nodes joined by commas.
Parameters:nodes (list) – Zero or more nodes.Returns:a NodeList
Represent a list of nodes joined by commas and wrapped in parentheses.
Parameters:query – Arbitrary filter expressions using Django-style lookups.
Represent a composable Django-style filter expression suitable for use withthe Model.filter()
or ModelSelect.filter()
methods.
- class
Tuple
(*args) - Represent a SQL row value.Row-values are supported by most databases.
- class
OnConflict
([action=None[, update=None[, preserve=None[, where=None[, conflict_target=None[, conflict_where=None[, conflict_constraint=None]]]]]]])
Parameters:
- action (str) – Action to take when resolving conflict.
- update – A dictionary mapping column to new value.
- preserve – A list of columns whose values should be preserved from the original INSERT. See also
EXCLUDED
. - where – Expression to restrict the conflict resolution.
- conflict_target – Column(s) that comprise the constraint.
- conflict_where – Expressions needed to match the constraint target if it is a partial index (index with a WHERE clause).
- conflict_constraint (str) – Name of constraint to use for conflictresolution. Currently only supported by Postgres.
Represent a conflict resolution clause for a data-modification query.
Depending on the database-driver being used, one or more of the aboveparameters may be required.
Parameters:columns – Columns whose values should be preserved.
Parameters:
- **_data** (_dict_) – Dictionary mapping column to new value.
- **kwargs** – Dictionary mapping column name to new value.
The update()
method supports being called with either a dictionaryof column-to-value, or keyword arguments representing the same.
Parameters:expressions – Expressions that restrict the action of theconflict resolution clause.
Parameters:constraints – Column(s) to use as target for conflict resolution.
Parameters:expressions – Expressions that match the conflict target index,in the case the conflict target is a partial index.
Parameters:constraint (str) – Name of constraints to use as target forconflict resolution. Currently only supported by Postgres.
- class
EXCLUDED
- Helper object that exposes the
EXCLUDED
namespace that is used withINSERT … ON CONFLICT
to reference values in the conflicting data.This is a “magic” helper, such that one uses it by accessing attributes onit that correspond to a particular column.
Example:
- class KV(Model):
- key = CharField(unique=True)
- value = IntegerField()
- # Create one row.
- KV.create(key='k1', value=1)
- # Demonstrate usage of EXCLUDED.
- # Here we will attempt to insert a new value for a given key. If that
- # key already exists, then we will update its value with the *sum* of its
- # original value and the value we attempted to insert -- provided that
- # the new value is larger than the original value.
- query = (KV.insert(key='k1', value=10)
- .on_conflict(conflict_target=[KV.key],
- update={KV.value: KV.value + EXCLUDED.value},
- where=(EXCLUDED.value > KV.value)))
- # Executing the above query will result in the following data being
- # present in the "kv" table:
- # (key='k1', value=11)
- query.execute()
- # If we attempted to execute the query *again*, then nothing would be
- # updated, as the new value (10) is now less than the value in the
- # original row (11).
- class
BaseQuery
The parent class from which all other query classes are derived. While youwill not deal with
BaseQuery
directly in your code, itimplements some methods that are common across all query types.
Parameters:database (Database) – Database to execute query against.
Bind the query to the given database for execution.
Parameters:as_dict (bool) – Specify whether to return rows as dictionaries.
Return rows as dictionaries.
Parameters:as_tuple (bool) – Specify whether to return rows as tuples.
Return rows as tuples.
Parameters:as_namedtuple (bool) – Specify whether to return rows as namedtuples.
Return rows as named tuples.
Parameters:constructor – Function that accepts row dict and returns anarbitrary object.
Return rows as arbitrary objects using the given constructor.
Returns:A 2-tuple consisting of the query’s SQL and parameters.
Parameters:database (Database) – Database to execute query against. Notrequired if query was previously bound to a database.
Execute the query and return result (depends on type of query beingexecuted). For example, select queries the return result will be aniterator over the query results.
Parameters:database (Database) – Database to execute query against. Notrequired if query was previously bound to a database.
Execute the query and return an iterator over the result-set. For largeresult-sets this method is preferable as rows are not cached in-memoryduring iteration.
Note
Because rows are not cached, the query may only be iterated overonce. Subsequent iterations will return empty result-sets as thecursor will have been consumed.
Example:
- query = StatTbl.select().order_by(StatTbl.timestamp).tuples()
- for row in query.iterator(db):
- process_row(row)
Unlike iterator()
, this method will cause rows tobe cached in order to allow efficient iteration, indexing and slicing.
Parameters:value – Either an integer index or a slice.
Retrieve a row or range of rows from the result-set.
Warning
This does not issue a COUNT()
query. Instead, the result-setis loaded as it would be during normal iteration, and the lengthis determined from the size of the result set.
Parameters:
- sql (str) – SQL query.
- params (tuple) – Parameters (optional).
Create a query by directly specifying the SQL to execute.
Parameters:
- where – Representation of WHERE clause.
- order_by (tuple) – Columns or values to order by.
- limit (int) – Value of LIMIT clause.
- offset (int) – Value of OFFSET clause.
Base-class for queries that support method-chaining APIs.
Parameters:cte_list – zero or more CTE
objects.
Include the given common-table expressions in the query. Any previouslyspecified CTEs will be overwritten. For examples of common-tableexpressions, see Common Table Expressions.
Parameters:expressions – zero or more expressions to include in the WHEREclause.
Include the given expressions in the WHERE clause of the query. Theexpressions will be AND-ed together with any previously-specifiedWHERE expressions.
Example selection users where the username is equal to ‘somebody’:
- sq = User.select().where(User.username == 'somebody')
Example selecting tweets made by users who are either editors oradministrators:
- sq = Tweet.select().join(User).where(
- (User.is_editor == True) |
- (User.is_admin == True))
Example of deleting tweets by users who are no longer active:
- inactive_users = User.select().where(User.active == False)
- dq = (Tweet
- .delete()
- .where(Tweet.user.in_(inactive_users)))
- dq.execute() # Return number of tweets deleted.
Note
where()
calls are chainable. Multiple calls willbe “AND”-ed together.
Parameters:expressions – zero or more expressions to include in the WHEREclause.
Include the given expressions in the WHERE clause of the query. Thismethod is the same as the Query.where()
method, except thatthe expressions will be OR-ed together with any previously-specifiedWHERE expressions.
Parameters:values – zero or more Column-like objects to order by.
Define the ORDER BY clause. Any previously-specified values will beoverwritten.
Parameters:values – zero or more Column-like objects to order by.
Extend any previously-specified ORDER BY clause with the given values.
Parameters:value (int) – specify value for LIMIT clause.
Parameters:value (int) – specify value for OFFSET clause.
Parameters:
- **page** (_int_) – Page number of results (starting from 1).
- **paginate_by** (_int_) – Rows-per-page.
Convenience method for specifying the LIMIT and OFFSET in a moreintuitive way.
This feature is designed with web-site pagination in mind, so the firstpage starts with page=1
.
- class
SelectQuery
Select query helper-class that implements operator-overloads for creatingcompound queries.
Parameters:
- **name** (_str_) – Alias for common table expression.
- **recursive** (_bool_) – Will this be a recursive CTE?
- **columns** (_list_) – List of column names (as strings).
Indicate that a query will be used as a common table expression. Forexample, if we are modelling a category tree and are using aparent-link foreign key, we can retrieve all categories and theirabsolute depths using a recursive CTE:
- class Category(Model):
- name = TextField()
- parent = ForeignKeyField('self', backref='children', null=True)
- # The base case of our recursive CTE will be categories that are at
- # the root level -- in other words, categories without parents.
- roots = (Category
- .select(Category.name, Value(0).alias('level'))
- .where(Category.parent.is_null())
- .cte(name='roots', recursive=True))
- # The recursive term will select the category name and increment
- # the depth, joining on the base term so that the recursive term
- # consists of all children of the base category.
- RTerm = Category.alias()
- recursive = (RTerm
- .select(RTerm.name, (roots.c.level + 1).alias('level'))
- .join(roots, on=(RTerm.parent == roots.c.id)))
- # Express <base term> UNION ALL <recursive term>.
- cte = roots.union_all(recursive)
- # Select name and level from the recursive CTE.
- query = (cte
- .select_from(cte.c.name, cte.c.level)
- .order_by(cte.c.name))
- for category in query:
- print(category.name, category.level)
For more examples of CTEs, see Common Table Expressions.
Parameters:columns – one or more columns to select from the inner query.Returns:a new query that wraps the calling query.
Create a new query that wraps the current (calling) query. For example,suppose you have a simple UNION
query, and need to apply anaggregation on the union result-set. To do this, you need to writesomething like:
- SELECT "u"."owner", COUNT("u"."id") AS "ct"
- FROM (
- SELECT "id", "owner", ... FROM "cars"
- UNION
- SELECT "id", "owner", ... FROM "motorcycles"
- UNION
- SELECT "id", "owner", ... FROM "boats") AS "u"
- GROUP BY "u"."owner"
The select_from()
method is designed to simplifyconstructing this type of query.
Example peewee code:
- class Car(Model):
- owner = ForeignKeyField(Owner, backref='cars')
- # ... car-specific fields, etc ...
- class Motorcycle(Model):
- owner = ForeignKeyField(Owner, backref='motorcycles')
- # ... motorcycle-specific fields, etc ...
- class Boat(Model):
- owner = ForeignKeyField(Owner, backref='boats')
- # ... boat-specific fields, etc ...
- cars = Car.select(Car.owner)
- motorcycles = Motorcycle.select(Motorcycle.owner)
- boats = Boat.select(Boat.owner)
- union = cars | motorcycles | boats
- query = (union
- .select_from(union.c.owner, fn.COUNT(union.c.id))
- .group_by(union.c.owner))
unionall
(_dest)Create a UNION ALL query with
dest
.Create a UNION ALL query with
dest
.Create a UNION query with
dest
.Create a UNION query with
dest
.Create an INTERSECT query with
dest
.Create an INTERSECT query with
dest
.Create an EXCEPT query with
dest
. Note that the method name has atrailing “_” character sinceexcept
is a Python reserved word.- Create an EXCEPT query with
dest
.
- class
SelectBase
Base-class for
Select
andCompoundSelect
queries.
Parameters:
- **database** ([_Database_](#Database)) – database to execute query against.
- **n** (_int_) – Number of rows to return.Returns:
A single row if n = 1, else a list of rows.
Execute the query and return the given number of rows from the startof the cursor. This function may be called multiple times safely, andwill always return the first N rows of results.
Parameters:
- **database** ([_Database_](#Database)) – database to execute query against.
- **n** (_int_) – Number of rows to return.Returns:
A single row if n = 1, else a list of rows.
Like the peek()
method, except a LIMIT
isapplied to the query to ensure that only n
rows are returned.Multiple calls for the same value of n
will not result in multipleexecutions.
Parameters:
- **database** ([_Database_](#Database)) – database to execute query against.
- **as_tuple** (_bool_) – Return the result as a tuple?Returns:
Single scalar value if as_tuple = False
, else row tuple.
Return a scalar value from the first row of results. If multiplescalar values are anticipated (e.g. multiple aggregations in a singlequery) then you may specify as_tuple=True
to get the row tuple.
Example:
- query = Note.select(fn.MAX(Note.timestamp))
- max_ts = query.scalar(db)
- query = Note.select(fn.MAX(Note.timestamp), fn.COUNT(Note.id))
- max_ts, n_notes = query.scalar(db, as_tuple=True)
Parameters:
- **database** ([_Database_](#Database)) – database to execute query against.
- **clear_limit** (_bool_) – Clear any LIMIT clause when counting.Returns:
Number of rows in the query result-set.
Return number of rows in the query result-set.
Implemented by running SELECT COUNT(1) FROM (
Parameters:database (Database) – database to execute query against.Returns:Whether any results exist for the current query.
Return a boolean indicating whether the current query has any results.
Parameters:database (Database) – database to execute query against.Returns:A single row from the database or None
.
Execute the query and return the first row, if it exists. Multiplecalls will result in multiple queries being executed.
Parameters:
- lhs (SelectBase) – A Select or CompoundSelect query.
- op (str) – Operation (e.g. UNION, INTERSECT, EXCEPT).
- rhs (SelectBase) – A Select or CompoundSelect query.
Class representing a compound SELECT query.
- class
Select
([from_list=None[, columns=None[, group_by=None[, having=None[, distinct=None[, windows=None[, for_update=None[, for_update_of=None[, for_update_nowait=None[, **kwargs]]]]]]]]]])
Parameters:
- from_list (list) – List of sources for FROM clause.
- columns (list) – Columns or values to select.
- group_by (list) – List of columns or values to group by.
- having (Expression) – Expression for HAVING clause.
- distinct – Either a boolean or a list of column-like objects.
- windows (list) – List of
Window
clauses. - for_update – Boolean or str indicating if SELECT…FOR UPDATE.
- for_update_of – One or more tables for FOR UPDATE OF clause.
- for_update_nowait (bool) – Specify NOWAIT locking.
Class representing a SELECT query.
Note
Rather than instantiating this directly, most-commonly you will use afactory method like Table.select()
or Model.select()
.
Methods on the select query can be chained together.
Example selecting some user instances from the database. Only the id
and username
columns are selected. When iterated, will return instancesof the User
model:
- query = User.select(User.id, User.username)
- for user in query:
- print(user.username)
Example selecting users and additionally the number of tweets made by theuser. The User
instances returned will have an additional attribute,‘count’, that corresponds to the number of tweets made:
- query = (User
- .select(User, fn.COUNT(Tweet.id).alias('count'))
- .join(Tweet, JOIN.LEFT_OUTER)
- .group_by(User))
- for user in query:
- print(user.username, 'has tweeted', user.count, 'times')
Note
While it is possible to instantiate Select
directly, morecommonly you will build the query using the method-chaining APIs.
Parameters:columns – Zero or more column-like objects to SELECT.
Specify which columns or column-like values to SELECT.
Parameters:columns – Zero or more column-like objects to SELECT.
Same as Select.columns()
, provided forbackwards-compatibility.
Parameters:columns – Zero or more column-like objects to SELECT.
Extend the current selection with the given columns.
Example:
- def get_users(with_count=False):
- query = User.select()
- if with_count:
- query = (query
- .select_extend(fn.COUNT(Tweet.id).alias('count'))
- .join(Tweet, JOIN.LEFT_OUTER)
- .group_by(User))
- return query
from
(*sources)[](#Select.from)
Parameters:sources – Zero or more sources for the FROM clause.
Specify which table-like objects should be used in the FROM clause.
- User = Table('users')
- Tweet = Table('tweets')
- query = (User
- .select(User.c.username, Tweet.c.content)
- .from_(User, Tweet)
- .where(User.c.id == Tweet.c.user_id))
- for row in query.execute(db):
- print(row['username'], '->', row['content'])
Parameters:
- **dest** – A table or table-like object.
- **join_type** (_str_) – Type of JOIN, default is “INNER”.
- **on** ([_Expression_](#Expression)) – Join predicate.
Join type may be one of:
- <code>JOIN.INNER</code>
- <code>JOIN.LEFT_OUTER</code>
- <code>JOIN.RIGHT_OUTER</code>
- <code>JOIN.FULL</code>
- <code>JOIN.FULL_OUTER</code>
- <code>JOIN.CROSS</code>
Express a JOIN:
- User = Table('users', ('id', 'username'))
- Note = Table('notes', ('id', 'user_id', 'content'))
- query = (Note
- .select(Note.content, User.username)
- .join(User, on=(Note.user_id == User.id)))
Parameters:values – zero or more Column-like objects to group by.
Define the GROUP BY clause. Any previously-specified values will beoverwritten.
Additionally, to specify all columns on a given table, you can pass thetable/model object in place of the individual columns.
Example:
- query = (User
- .select(User, fn.Count(Tweet.id).alias('count'))
- .join(Tweet)
- .group_by(User))
Parameters:values – zero or more Column-like objects to group by.
Extend the GROUP BY clause with the given columns.
Parameters:expressions – zero or more expressions to include in the HAVINGclause.
Include the given expressions in the HAVING clause of the query. Theexpressions will be AND-ed together with any previously-specifiedHAVING expressions.
Parameters:columns – Zero or more column-like objects.
Indicate whether this query should use a DISTINCT clause. By specifyinga single value of True
the query will use a simple SELECT DISTINCT.Specifying one or more columns will result in a SELECT DISTINCT ON.
Parameters:windows – zero or more Window
objects.
Define the WINDOW clause. Any previously-specified values will beoverwritten.
Example:
- # Equivalent example Using a Window() instance instead.
- window = Window(partition_by=[Sample.counter])
- query = (Sample
- .select(
- Sample.counter,
- Sample.value,
- fn.AVG(Sample.value).over(window))
- .window(window) # Note call to ".window()"
- .order_by(Sample.counter))
Parameters:
- **for_update** – Either a boolean or a string indicating thedesired expression, e.g. “FOR SHARE”.
- **of** – One or more models to restrict locking to.
- **nowait** (_bool_) – Specify NOWAIT option when locking.
Parameters:
- table (Table) – Table to write to.
- returning (list) – List of columns for RETURNING clause.
Base-class for write queries.
Parameters:returning – Zero or more column-like objects for RETURNING clause
Specify the RETURNING clause of query (if supported by your database).
- query = (User
- .insert_many([{'username': 'foo'},
- {'username': 'bar'},
- {'username': 'baz'}])
- .returning(User.id, User.username)
- .namedtuples())
- data = query.execute()
- for row in data:
- print('added:', row.username, 'with id=', row.id)
Parameters:
- table (Table) – Table to update.
- update (dict) – Data to update.
Class representing an UPDATE query.
Example:
- PageView = Table('page_views')
- query = (PageView
- .update({PageView.c.page_views: PageView.c.page_views + 1})
- .where(PageView.c.url == url))
- query.execute(database)
from
(*sources)[](#Update.from)
Parameters:sources (Source) – one or more Table
,Model
, query, or ValuesList
to join with.
Specify additional tables to join with using the UPDATE … FROMsyntax, which is supported by Postgres. The Postgres documentationprovides additional detail, but to summarize:
When aFROM
clause is present, what essentially happens is thatthe target table is joined to the tables mentioned in thefrom_list, and each output row of the join represents an updateoperation for the target table. When usingFROM
you shouldensure that the join produces at most one output row for each rowto be modified.
Example:
- # Update multiple users in a single query.
- data = [('huey', True),
- ('mickey', False),
- ('zaizee', True)]
- vl = ValuesList(data, columns=('username', 'is_admin'), alias='vl')
- # Here we'll update the "is_admin" status of the above users,
- # "joining" the VALUES() on the "username" column.
- query = (User
- .update(is_admin=vl.c.is_admin)
- .from_(vl)
- .where(User.username == vl.c.username))
The above query produces the following SQL:
- UPDATE "users" SET "is_admin" = "vl"."is_admin"
- FROM (
- VALUES ('huey', t), ('mickey', f), ('zaizee', t))
- AS "vl"("username", "is_admin")
- WHERE ("users"."username" = "vl"."username")
Parameters:
- table (Table) – Table to INSERT data into.
- insert – Either a dict, a list, or a query.
- columns (list) – List of columns when
insert
is a list or query. - on_conflict – Conflict resolution strategy.
Class representing an INSERT query.
Parameters:ignore (bool) – Whether to add ON CONFLICT IGNORE clause.
Specify IGNORE conflict resolution strategy.
Parameters:replace (bool) – Whether to add ON CONFLICT REPLACE clause.
Specify REPLACE conflict resolution strategy.
onconflict
([_action=None[, update=None[, preserve=None[, where=None[, conflict_target=None[, conflict_where=None[, conflict_constraint=None]]]]]]])
Parameters:
- **action** (_str_) – Action to take when resolving conflict. If blank,action is assumed to be “update”.
- **update** – A dictionary mapping column to new value.
- **preserve** – A list of columns whose values should be preserved from the original INSERT.
- **where** – Expression to restrict the conflict resolution.
- **conflict_target** – Column(s) that comprise the constraint.
- **conflict_where** – Expressions needed to match the constraint target if it is a partial index (index with a WHERE clause).
- **conflict_constraint** (_str_) – Name of constraint to use for conflictresolution. Currently only supported by Postgres.
Specify the parameters for an OnConflict
clause to use forconflict resolution.
Examples:
- class User(Model):
- username = TextField(unique=True)
- last_login = DateTimeField(null=True)
- login_count = IntegerField()
- def log_user_in(username):
- now = datetime.datetime.now()
- # INSERT a new row for the user with the current timestamp and
- # login count set to 1. If the user already exists, then we
- # will preserve the last_login value from the "insert()" clause
- # and atomically increment the login-count.
- userid = (User
- .insert(username=username, last_login=now, login_count=1)
- .on_conflict(
- conflict_target=[User.username],
- preserve=[User.last_login],
- update={User.login_count: User.login_count + 1})
- .execute())
- return userid
Example using the special EXCLUDED
namespace:
- class KV(Model):
- key = CharField(unique=True)
- value = IntegerField()
- # Create one row.
- KV.create(key='k1', value=1)
- # Demonstrate usage of EXCLUDED.
- # Here we will attempt to insert a new value for a given key. If that
- # key already exists, then we will update its value with the *sum* of its
- # original value and the value we attempted to insert -- provided that
- # the new value is larger than the original value.
- query = (KV.insert(key='k1', value=10)
- .on_conflict(conflict_target=[KV.key],
- update={KV.value: KV.value + EXCLUDED.value},
- where=(EXCLUDED.value > KV.value)))
- # Executing the above query will result in the following data being
- # present in the "kv" table:
- # (key='k1', value=11)
- query.execute()
- # If we attempted to execute the query *again*, then nothing would be
- # updated, as the new value (10) is now less than the value in the
- # original row (11).
Parameters:
- name (str) – Index name.
- table (Table) – Table to create index on.
- expressions – List of columns to index on (or expressions).
- unique (bool) – Whether index is UNIQUE.
- safe (bool) – Whether to add IF NOT EXISTS clause.
- where (Expression) – Optional WHERE clause for index.
- using (str) – Index algorithm.
Parameters:_safe (bool) – Whether to add IF NOT EXISTS clause.
Parameters:expressions – zero or more expressions to include in the WHEREclause.
Include the given expressions in the WHERE clause of the index. Theexpressions will be AND-ed together with any previously-specifiedWHERE expressions.
Parameters:_using (str) – Specify index algorithm for USING clause.
- class
ModelIndex
(model, fields[, unique=False[, safe=True[, where=None[, using=None[, name=None]]]]])
Parameters:
- model (Model) – Model class to create index on.
- fields (list) – Fields to index.
- unique (bool) – Whether index is UNIQUE.
- safe (bool) – Whether to add IF NOT EXISTS clause.
- where (Expression) – Optional WHERE clause for index.
- using (str) – Index algorithm or type, e.g. ‘BRIN’, ‘GiST’ or ‘GIN’.
- name (str) – Optional index name.
Expressive method for declaring an index on a model.
Examples:
- class Article(Model):
- name = TextField()
- timestamp = TimestampField()
- status = IntegerField()
- flags = BitField()
- is_sticky = flags.flag(1)
- is_favorite = flags.flag(2)
- # CREATE INDEX ... ON "article" ("name", "timestamp")
- idx = ModelIndex(Article, (Article.name, Article.timestamp))
- # CREATE INDEX ... ON "article" ("name", "timestamp") WHERE "status" = 1
- idx = idx.where(Article.status == 1)
- # CREATE UNIQUE INDEX ... ON "article" ("timestamp" DESC, "flags" & 2) WHERE "status" = 1
- idx = ModelIndex(
- Article,
- (Article.timestamp.desc(), Article.flags.bin_and(2)),
- unique = True).where(Article.status == 1)
You can also use Model.index()
:
- idx = Article.index(Article.name, Article.timestamp).where(Article.status == 1)
To add an index to a model definition use Model.add_index()
:
- idx = Article.index(Article.name, Article.timestamp).where(Article.status == 1)
- # Add above index definition to the model definition. When you call
- # Article.create_table() (or database.create_tables([Article])), the
- # index will be created.
- Article.add_index(idx)