From 3ca7c47ddc417b2b75dc417c329b0f63eda26b7f Mon Sep 17 00:00:00 2001 From: MilagrosMarin Date: Thu, 3 Sep 2026 15:48:39 +0200 Subject: [PATCH] docs(codecs): thread the connection config in the SchemaCodec example The subclass example omitted config= on both _build_path and _get_backend, so a codec written from it resolves its store against the module-level dj.config instead of the calling connection's. In a process holding connections for several users that config belongs to none of them, and on a pod with no ambient credentials it belongs to nothing at all. The built-in object and npy codecs already read key["_config"] and pass it to both helpers; the example now shows the same, and a note above it says why. The example also omitted store_name on _build_path, which is where partition and prefix settings come from. Docs only: the executable AST is unchanged. --- src/datajoint/builtin_codecs/schema.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/datajoint/builtin_codecs/schema.py b/src/datajoint/builtin_codecs/schema.py index 11c6c5750..260560f4d 100644 --- a/src/datajoint/builtin_codecs/schema.py +++ b/src/datajoint/builtin_codecs/schema.py @@ -28,6 +28,11 @@ class SchemaCodec(Codec, register=False): - ``_build_path()``: Construct storage path from context - ``_get_backend()``: Get storage backend by name + Both helpers take a ``config`` and fall back to the global ``dj.config`` + without one. Read it off ``key["_config"]`` and pass it through, as below: it + is the calling connection's config, and in a process holding connections for + several users the global one belongs to none of them. + Comparison with Hash-addressed: - **Schema-addressed** (this): Path from schema structure, no dedup - **Hash-addressed**: Path from content hash, automatic dedup @@ -39,13 +44,18 @@ class MyCodec(SchemaCodec): def encode(self, value, *, key=None, store_name=None): schema, table, field, pk = self._extract_context(key) - path, _ = self._build_path(schema, table, field, pk, ext=".dat") - backend = self._get_backend(store_name) + config = (key or {}).get("_config") + path, _ = self._build_path( + schema, table, field, pk, ext=".dat", + store_name=store_name, config=config, + ) + backend = self._get_backend(store_name, config=config) backend.put_buffer(serialize(value), path) return {"path": path, "store": store_name, ...} def decode(self, stored, *, key=None): - backend = self._get_backend(stored.get("store")) + config = (key or {}).get("_config") + backend = self._get_backend(stored.get("store"), config=config) return MyRef(stored, backend) See Also