Apocryphes¶
Estoult includes a number of extensions in the apocryphes
namespace.
Connection pooling¶
Lightweight connection pooling. This is heavily recommended for multi-threaded applications (e.g webservers).
In a multi-threaded application, up to max_connections
will be opened. Each
thread (or, if using gevent, greenlet) will have it’s own connection.
In a single-threaded application, only one connection will be created. It will
be continually recycled until either it exceeds the stale timeout or is closed
explicitly (using .manual_close()
).
from apocryphes.pool import PooledPostgreSQLDatabase
db = PooledPostgreSQLDatabase(
max_connections=32,
stale_timeout=300,
user=os.getenv("POSTGRES_USER", "postgres"),
password=os.getenv("POSTGRES_PASSWORD", "postgres"),
host=os.getenv("POSTGRES_HOST", "localhost"),
database=os.getenv("POSTGRES_DB", "porg"),
)
Warning
autoconnect
is disabled so your application needs to ensure that connections are
opened and closed when you are finished with them, so they can be returned to the
pool. With a Flask server, it could look like this:
@app.before_request
def open_connection():
db.connect()
@app.teardown_request
def close_connection(exc):
db.close()
-
class
apocryphes.pool.
PooledMySQLDatabase
(max_connections=20, stale_timeout=None, timeout=None, *args, **kwargs)¶ Bases:
apocryphes.pool.PooledDatabase
,estoult.MySQLDatabase
-
class
apocryphes.pool.
PooledPostgreSQLDatabase
(max_connections=20, stale_timeout=None, timeout=None, *args, **kwargs)¶ Bases:
apocryphes.pool.PooledDatabase
,estoult.PostgreSQLDatabase
-
class
apocryphes.pool.
PooledSQLiteDatabase
(max_connections=20, stale_timeout=None, timeout=None, *args, **kwargs)¶ Bases:
apocryphes.pool.PooledDatabase
,estoult.SQLiteDatabase
Rider¶
rider
is a simple CLI tool to help manage database migrations using the existing
Estoult database object.
Start by creating a rider.py
file to tell rider
about your database object.
from src.schemas.base import db
# Export the db
# Not actually needed, but my linter screams at me otherwise
db = db
# Default config
config = {
# Path where migrations are stored
"source": "./migrations",
# Table name for migrations
"table_name": "_rider_migrations",
# Table name of migration logs
"log_name": "_rider_logs",
}
Create a new migration with a description.
rider create -m "add contacts table"
This will create the bellow scaffold file in which you can add your migration steps too.
'''
create table
'''
from apocryphes.rider import step
__depends__ = {"1602721237-add-pg-extensions"}
steps = [
step("")
]
The step
function takes 3 arguments:
migrate
: a SQL query or function to apply the migration step.rollback
: (optional) a SQL query or function to rollback the migration step.ignore_errors
: (optional, one of “migrate”, “rollback” or “all”) causes rider to ignore database errors in either migrate, rollback, or both stages.
steps = [
# Steps with sql queries
step(
migrate="create table contacts (id int not null);",
rollback="drop table contacts;",
ignore_errors="all",
),
# Arguments don't need to be kwargs
step("alter table contacts add column name varchar(256) not null")
]
You can supply a function to migrate
or rolllback
. Each function takes your db
object.
def migrate_step(db):
db.sql(...)
def rollback_step(db):
db.sql(...)
steps = [
step(migrate_step, rollback_step),
]
View all migrations with their index/message/applied at time:
rider migrations
Apply migrations:
rider migrate
Rollback database to a migration.
# Migration indicies can be found in the `migrations` list
rider migrations
# Rollback to 8th migration (index starts at 0)
rider rollback -i 7
-
class
apocryphes.rider.
Rider
(db, config={})¶ Bases:
object
-
applied_at
(id)¶
-
config
= {'log_name': '_rider_logs', 'source': './migrations', 'table_name': '_rider_migrations'}¶
-
create
(args)¶
-
get_migrations
()¶
-
init_tables
(*args, **kwargs)¶
-
migrate
(*args, **kwargs)¶
-
migrations
(*args, **kwargs)¶
-
parse_args
()¶
-
rollback
(*args, **kwargs)¶
-
run
(*args, **kwargs)¶
-
-
apocryphes.rider.
step
¶ alias of
apocryphes.rider.Step