Database Configuration
Version 1 · Initial DB configuration page: db.json resolution order, the qdb/qdgwiki aliases, the strict-mode safety check, and the PyMySQL shim — verified directly against qwebhub/config.py
Historical versionQWebHub Database Configuration
All DB config resolution lives in one place: qwebhub/config.py. Modules
mounted under the hub defer to this instead of each reading their own
db.json, as they did before being unified under QWebHub.
Why this exists
Historically each module resolved db.json from a different path
(C:\Users\Robert\Claude\db.json, C:\Users\Robert\db.json,
C:\Users\Robert\projects_config\db.json). QWebHub picks ONE resolution
order and every mounted module defers to the hub's DATABASES setting —
modules keep their own raw-SQL helpers (db.py / connection.cursor()),
they just don't read db.json themselves anymore once mounted.
db.json resolution order (first hit wins)
QWEBHUB_DB_JSONenv var, if set and the file exists.C:\Users\Robert\projects_config\db.jsonC:\Users\Robert\db.json- If none exist: falls back to individual env vars
(
QWEBHUB_DB_HOST/_PORT/_NAME/_USER/_PASS) somanage.py checkand tests can run with nodb.jsonon disk at all.
Two database aliases
qdb_alias(strict=True) — the shared qdb schema (QDBAdmin + QProcess)
Builds DATABASES['default'] from the resolved db.json/env config. With
strict=True (the default), it asserts the resolved database value is
literally "qdb" and raises ConfigError if not.
Why the strict check exists: db.json is shared across projects, and
has in the past silently pointed at the wrong schema (the old rs/RAS
schema) for a different project's sake. Failing loudly at startup is
deliberate — better than a module silently reading/writing the wrong
database. strict=False is only for a throwaway local experiment; don't use
it as a routine workaround. QWEBHUB_DB_STRICT=0 (checked via
qdb_strict_enabled()) disables the check globally if genuinely needed.
qdgwiki_alias() — the read-only Knowledge Base schema
Same credential source as qdb_alias, but the schema name is hardcoded to
"qdgwiki" regardless of what db.json says — so a shared, mutable
db.json can never accidentally redirect Knowledge Base reads to the wrong
database. Used by the qdgkb module (QDG KB Viewer).
Both aliases set init_command: SET sql_mode='STRICT_TRANS_TABLES' and
charset: utf8mb4.
PyMySQL-as-MySQLdb shim
install_pymysql_shim() installs PyMySQL as a drop-in for MySQLdb, once,
here — moved from QProcess's own settings.py (which used to do this
itself) so it's installed exactly once regardless of which modules are
enabled. It also spoofs PyMySQL's reported version to (2, 2, 1, "final", 0)
/ "2.2.1", because Django's MySQL backend checks Database.__version__
against mysqlclient's versioning scheme (requires >= 2.2.1) — PyMySQL
reports its own (lower) version number, which would otherwise fail that
check even though PyMySQL works fine as the actual driver.
Shared static/template directory resolution
Also centralized here, for the same "resolve once, not per-module" reason:
global_static_dirs(projects_root)— findsGlobal Memory/CSS,Global Memory/Icons,Global Assests/Admin Imagesif present.module_template_dirs(modules)/module_static_dirs(modules)— per enabled module, adds<project_root>/templatesand<project_root>/staticto Django's search paths (see Architecture for the namespacing rule this depends on).
Related pages
- Architecture — the module registry these aliases and directory helpers plug into.
- Odin Deployment / QWebHub Q&A — credential handling for the FTP deployment path (separate from DB credentials).