Django SQLFun allows you to define and manage custom SQL functions in code. When you change the function definitions and call makemigrations
, it will generate migrations for any functions that have been added, removed, or changed. These function classes can also be used in Django querysets since the SqlFun
class inherits from django.db.models.expressions.Func
.
Note: I'm still developing this so there may be some rough edges. Breaking changes may happen.
- Install using your favorite python package manager, eg.
pip install django-sqlfun
. - Add
sqlfun
toINSTALLED_APPS
in your django settings - Run
manage.py migrate
. This will set up any tables required bysqlfun
to keep track of your custom funcitons
- Define a custom function in a module that gets imported on project load (eg.
models.py
). See below for example, or thetest_project
. - Run
manage.py makemigrations
- Run
manage.py migrate
Define a custom function in your models.py
:
# models.py
from sqlfun import SqlFun
from django.db.models import IntegerField
class BadSum(SqlFun):
"""Almost returns the sum of two numbers."""
app_label = 'test_project' # [optional] if omitted, sqlfun will atempt to auto-resolve it
sql = """
CREATE OR REPLACE FUNCTION bad_sum(
first integer,
second integer
) RETURNS integer as $$
SELECT first + second + 1;
$$
LANGUAGE sql
stable;
"""
output_field = IntegerField()
Then run manage.py makemigrations
and manage.py migrate
and you should be good to go. You can use it in SQL: SELECT bad_sum(2, 2)
, or in a Python queryset like so: MyModel.objects.annotate(foo=BadSum(Value(2), Value(2)))
.
- SQL functions are normalized, so changes in white-space should not result in changes being detected
- the
--dry-run
and--name
options ofmakemigrations
are respected
These instructions assume a recent Ubuntu/Debian environment.
- Clone the repository
- If needed, install
python3-venv
andpython3-pip
packages - Create a virtual environment
python3 -m venv .venv
- Install
libpq-dev
package sincepsycopg2
depends on it. - Install
pdm
:pip3 install --user pdm
- Install dev dependencies with
pdm install --dev
Testing also requires a recent install of docker which is used to spin up a test postgres instance.
This project is inspired by two great projects: django-pgtrigger
and django-pgviews
.