mirror of
https://git.anonymousland.org/anonymousland/synapse-product.git
synced 2025-01-12 08:39:32 -05:00
Minor updates, and docs, for schema delta files (#11823)
* Make functions in python deltas optional It's annoying to always have to write stubs for these. * Documentation for delta files * changelog
This commit is contained in:
parent
4210143f53
commit
fc8598bc87
1
changelog.d/11823.misc
Normal file
1
changelog.d/11823.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Minor updates and documentation for database schema delta files.
|
@ -96,6 +96,60 @@ Ensure postgres is installed, then run:
|
|||||||
NB at the time of writing, this script predates the split into separate `state`/`main`
|
NB at the time of writing, this script predates the split into separate `state`/`main`
|
||||||
databases so will require updates to handle that correctly.
|
databases so will require updates to handle that correctly.
|
||||||
|
|
||||||
|
## Delta files
|
||||||
|
|
||||||
|
Delta files define the steps required to upgrade the database from an earlier version.
|
||||||
|
They can be written as either a file containing a series of SQL statements, or a Python
|
||||||
|
module.
|
||||||
|
|
||||||
|
Synapse remembers which delta files it has applied to a database (they are stored in the
|
||||||
|
`applied_schema_deltas` table) and will not re-apply them (even if a given file is
|
||||||
|
subsequently updated).
|
||||||
|
|
||||||
|
Delta files should be placed in a directory named `synapse/storage/schema/<database>/delta/<version>/`.
|
||||||
|
They are applied in alphanumeric order, so by convention the first two characters
|
||||||
|
of the filename should be an integer such as `01`, to put the file in the right order.
|
||||||
|
|
||||||
|
### SQL delta files
|
||||||
|
|
||||||
|
These should be named `*.sql`, or — for changes which should only be applied for a
|
||||||
|
given database engine — `*.sql.posgres` or `*.sql.sqlite`. For example, a delta which
|
||||||
|
adds a new column to the `foo` table might be called `01add_bar_to_foo.sql`.
|
||||||
|
|
||||||
|
Note that our SQL parser is a bit simple - it understands comments (`--` and `/*...*/`),
|
||||||
|
but complex statements which require a `;` in the middle of them (such as `CREATE
|
||||||
|
TRIGGER`) are beyond it and you'll have to use a Python delta file.
|
||||||
|
|
||||||
|
### Python delta files
|
||||||
|
|
||||||
|
For more flexibility, a delta file can take the form of a python module. These should
|
||||||
|
be named `*.py`. Note that database-engine-specific modules are not supported here –
|
||||||
|
instead you can write `if isinstance(database_engine, PostgresEngine)` or similar.
|
||||||
|
|
||||||
|
A Python delta module should define either or both of the following functions:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import synapse.config.homeserver
|
||||||
|
import synapse.storage.engines
|
||||||
|
import synapse.storage.types
|
||||||
|
|
||||||
|
|
||||||
|
def run_create(
|
||||||
|
cur: synapse.storage.types.Cursor,
|
||||||
|
database_engine: synapse.storage.engines.BaseDatabaseEngine,
|
||||||
|
) -> None:
|
||||||
|
"""Called whenever an existing or new database is to be upgraded"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def run_upgrade(
|
||||||
|
cur: synapse.storage.types.Cursor,
|
||||||
|
database_engine: synapse.storage.engines.BaseDatabaseEngine,
|
||||||
|
config: synapse.config.homeserver.HomeServerConfig,
|
||||||
|
) -> None:
|
||||||
|
"""Called whenever an existing database is to be upgraded."""
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
## Boolean columns
|
## Boolean columns
|
||||||
|
|
||||||
Boolean columns require special treatment, since SQLite treats booleans the
|
Boolean columns require special treatment, since SQLite treats booleans the
|
||||||
|
@ -499,9 +499,12 @@ def _upgrade_existing_database(
|
|||||||
module = importlib.util.module_from_spec(spec)
|
module = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(module) # type: ignore
|
spec.loader.exec_module(module) # type: ignore
|
||||||
|
|
||||||
logger.info("Running script %s", relative_path)
|
if hasattr(module, "run_create"):
|
||||||
module.run_create(cur, database_engine) # type: ignore
|
logger.info("Running %s:run_create", relative_path)
|
||||||
if not is_empty:
|
module.run_create(cur, database_engine) # type: ignore
|
||||||
|
|
||||||
|
if not is_empty and hasattr(module, "run_upgrade"):
|
||||||
|
logger.info("Running %s:run_upgrade", relative_path)
|
||||||
module.run_upgrade(cur, database_engine, config=config) # type: ignore
|
module.run_upgrade(cur, database_engine, config=config) # type: ignore
|
||||||
elif ext == ".pyc" or file_name == "__pycache__":
|
elif ext == ".pyc" or file_name == "__pycache__":
|
||||||
# Sometimes .pyc files turn up anyway even though we've
|
# Sometimes .pyc files turn up anyway even though we've
|
||||||
|
Loading…
Reference in New Issue
Block a user