The ERPNext v15 Docker Compose stack is deployed and operational, built from /root/work/erpnext-deploy/. The SSO flow from GP Booking works and core accounting features are functional. However, several PostgreSQL compatibility issues remain in ERPNext's reports, which was originally built for MariaDB.
| Issue | Fix | Location |
|---|---|---|
FORCE INDEX (MySQL syntax) on PostgreSQL |
Monkey-patch via .pth file — silences FORCE INDEX for PostgreSQLQueryBuilder |
/home/frappe/frappe-bench/env/lib/python3.11/site-packages/_erpnext_patches.pth → patch_pypika_pg.py |
IF() → CASE WHEN conversion |
Applied in gunicorn_app.py WSGI wrapper before Frappe loads |
/opt/erpnext/gunicorn_app.py |
Non-aggregated columns missing from GROUP BY |
_fix_group_by() automatically adds columns |
Same as above |
Profit and Loss Statement / Purchase Order Trends reports (erpnext/controllers/trends.py, erpnext/accounts/report/financial_statements.py)
These use raw SQL with MySQL-specific syntax. The _fix_group_by patch should resolve most GroupingError issues, but there may be other reports with similar patterns.
Other raw SQL queries in ERPNext that use FORCE INDEX, IF(), or omit PostgreSQL-required GROUP BY columns. The gunicorn wrapper patch is generic and should catch most, but edge cases may exist.
The root cause: ERPNext v15 was designed for MariaDB. Full PostgreSQL support requires the Frappe/ERPNext ecosystem to be running on PostgreSQL from the start, or migrating all raw SQL. The patches are a pragmatic workaround.
erpnext.pth (Python site-packages .pth file):
import patch_pypika_pg
Automatically runs at every Python startup. Patches PyPika's query builder to skip FORCE INDEX on PostgreSQLQueryBuilder.
gunicorn_app.py (WSGI wrapper at /opt/erpnext/gunicorn_app.py):
PYTHONPATH=/opt/erpnext and gunicorn_app:applicationfrappe.database.postgres.database.modify_query before Frappe startsIF(cond, t, f) → CASE WHEN cond THEN t ELSE f ENDGROUP BY clausesdocker logs erpnext_web --tail 100bench --site test-client.accounts.gp.veripath.co.uk execute erpnext.controllers.trends.get_data --kwargs "{\"filters\": ...}"gunicorn_app in gunicorn's process args (ps aux | grep gunicorn)/app/buying in the browser