CrudDB¶
The CrudDB class inherits from Database to provide standard CRUD operations for a database table.
It requires the db extra to be installed:
It can be imported from fluid.db:
fluid.db.CrudDB
dataclass
¶
CrudDB(
dsn,
echo=(lambda: DBECHO)(),
pool_size=(lambda: DBPOOL_MAX_SIZE)(),
max_overflow=(lambda: DBPOOL_MAX_OVERFLOW)(),
pool_pre_ping=(lambda: DBPOOL_PRE_PING)(),
metadata=MetaData(),
migration_path="",
app_name=(lambda: APP_NAME)(),
_engine=None,
)
Bases: Database
A Database with additional methods for CRUD operations
dsn
instance-attribute
¶
data source name, aka connection string
Example: postgresql+asyncpg://user:password@localhost/dbname
Note that the +asyncpg part is important for the async engine.
Currently, only postgresql+asyncpg is supported, but other databases may
be supported in the future.
echo
class-attribute
instance-attribute
¶
Echo SQL queries to stdout
It defaults to the DBECHO setting in the settings module
pool_size
class-attribute
instance-attribute
¶
max_overflow
class-attribute
instance-attribute
¶
pool_pre_ping
class-attribute
instance-attribute
¶
Test pooled connections on checkout and replace the ones the server has dropped, e.g. on a database restart, rather than failing the next query
It defaults to the DBPOOL_PRE_PING setting in the settings module
migration_path
class-attribute
instance-attribute
¶
Path to the directory containing migration files. If empty, migrations will
be stored in the default location migrations in the current working directory.
app_name
class-attribute
instance-attribute
¶
engine
property
¶
The :class:sqlalchemy.ext.asyncio.AsyncEngine creating connection
and transactions
from_env
classmethod
¶
from_env(
*,
dsn=None,
schema=None,
migration_path=None,
app_name=None,
max_overflow=None,
pool_size=None,
db_name=None
)
Create a new database container from environment variables as defaults
Source code in fluid/db/container.py
connection
async
¶
Context manager for obtaining an asynchronous connection
ensure_connection
async
¶
Context manager for obtaining an asynchronous connection
Source code in fluid/db/container.py
transaction
async
¶
Context manager for initializing an asynchronous database transaction
ensure_transaction
async
¶
Context manager for ensuring we a connection has initialized a database transaction
Source code in fluid/db/container.py
close
async
¶
ping
async
¶
migration
¶
db_select
async
¶
Select rows from a given table
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to select from
TYPE:
|
filters
|
Key-value pairs for filtering rows; supports 'field:op' syntax for operators (eq, ne, gt, ge, lt, le)
TYPE:
|
order_by
|
Column names to order by; prefix with '-' for descending
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
columns
|
Columns to select, every column of the table when empty
TYPE:
|
Source code in fluid/db/crud.py
db_insert
async
¶
Insert one or more rows into a table, returning the inserted rows
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to insert into
TYPE:
|
data
|
A single row dict or a list of row dicts; missing columns in a multi-row insert are filled with None
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
Source code in fluid/db/crud.py
db_update
async
¶
Update rows matching the filters, returning all updated rows
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to update
TYPE:
|
filters
|
Key-value pairs identifying rows to update; supports 'field:op' syntax
TYPE:
|
data
|
Column values to set on the matching rows
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
Source code in fluid/db/crud.py
db_upsert
async
¶
Update a single row if it exists, otherwise insert it, returning the row
The operation is atomic: it issues a single
INSERT ... ON CONFLICT (...) DO UPDATE statement, so concurrent
upserts of the same row never violate the unique constraint.
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to upsert into
TYPE:
|
filters
|
Column values identifying the row; the columns must match a primary key or unique constraint of the table
TYPE:
|
data
|
Column values to set; if None, the row is fetched or inserted using only the filters
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
Source code in fluid/db/crud.py
db_upsert_many
async
¶
Update rows that exist and insert the others, returning all rows
Records are sent in batches of batch_size, each as a single
INSERT ... ON CONFLICT (...) DO UPDATE statement, all within one
transaction. The returned rows are not guaranteed to follow the order
of the records: match them by key.
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to upsert into
TYPE:
|
records
|
Rows to upsert; every row must have the same columns, including the key columns, and no two rows can share a key
TYPE:
|
key
|
Columns identifying a row; they must match a primary key or unique constraint of the table
TYPE:
|
batch_size
|
Maximum number of records sent in a single statement; Postgres accepts at most 32767 bind parameters per statement and each record uses one per column, so lower it for tables with more than 32 columns
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
Source code in fluid/db/crud.py
db_delete
async
¶
Delete rows matching the filters, returning the deleted rows
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to delete from
TYPE:
|
filters
|
Key-value pairs identifying rows to delete; supports 'field:op' syntax
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
Source code in fluid/db/crud.py
db_count
async
¶
Count rows in a table matching the given filters
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to count rows in
TYPE:
|
filters
|
Key-value pairs for filtering rows; supports 'field:op' syntax
TYPE:
|
conn
|
Optional existing connection to reuse
TYPE:
|
Source code in fluid/db/crud.py
insert_query
¶
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to insert into
TYPE:
|
records
|
A single row dict or a list of row dicts
TYPE:
|
Source code in fluid/db/crud.py
upsert_query
¶
Build an atomic INSERT ... ON CONFLICT (...) DO UPDATE query
On conflict, every column of the records that is not part of the key is updated with the new value.
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table to upsert into
TYPE:
|
records
|
Rows to upsert; every row must have the same columns
TYPE:
|
key
|
Columns identifying a row; they must match a primary key or unique constraint of the table
TYPE:
|
Source code in fluid/db/crud.py
get_query
¶
Apply filters from params to a SQLAlchemy query and return it
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table the query targets
TYPE:
|
sql_query
|
The base SQLAlchemy query to apply filters to
TYPE:
|
params
|
Key-value filter pairs; keys may use 'field:op' syntax
TYPE:
|
Source code in fluid/db/crud.py
db_count_query
¶
| PARAMETER | DESCRIPTION |
|---|---|
sql_query
|
The filtered SELECT query to wrap in a COUNT
TYPE:
|
order_by_query
¶
Apply ordering to a SELECT query
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table the query targets
TYPE:
|
sql_query
|
The SELECT query to add ordering to
TYPE:
|
order_by
|
Column names to order by; prefix with '-' for descending
TYPE:
|
Source code in fluid/db/crud.py
order_by_columns
¶
Return a list of SQLAlchemy column expressions for the given order_by fields
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table whose columns are referenced
TYPE:
|
order_by
|
Column names to order by; prefix with '-' for descending
TYPE:
|
Source code in fluid/db/crud.py
search_query
¶
Apply a case-insensitive substring search across the given columns
| PARAMETER | DESCRIPTION |
|---|---|
table
|
The table whose columns are searched
TYPE:
|
sql_query
|
The SELECT query to add the search filter to
TYPE:
|
search_fields
|
Column names to search across using ILIKE
TYPE:
|
search
|
Search text; empty string is a no-op
TYPE:
|
Source code in fluid/db/crud.py
default_filter_column
¶
Build a SQLAlchemy WHERE clause expression for a single column filter
| PARAMETER | DESCRIPTION |
|---|---|
column
|
The SQLAlchemy column to filter on
TYPE:
|
op
|
Comparison operator:
TYPE:
|
value
|
Comparison value; a list matches any / none of its values for
TYPE:
|