canonical / canonical/postgresql-single-kernel-library

Easier access to client-relation data

Open
#228 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
4
Forks
3
Avg merge
3d 17h
Merged PRs (30d)
26

Description

## Request

Raised as a drive-by nit on #216 ([comment](https://github.com/canonical/postgresql-single-kernel-library/pull/216#discussion_r3832000709), anchored on `DatabaseManager.set_rel_to_db_mapping`'s `rel_databases` round-trip and the per-field fetches in `collect_user_relations`): "Not sure it is helpful but what we did in opensearch and valkey is to have something like [this](https://github.com/canonical/opensearch-single-kernel-library/blob/2/edge/opensearch_single_kernel/core/external_clients_relation.py) which makes it easier to access data of relation. But this is a nit."

Today the client-relation data reads across `DatabaseManager` are untyped field fetches (`fetch_relation_field(relation.id, "database")`, raw `relation.data.values()` loops) rather than one named accessor.

An implementation of the typed-models shape below was explored in #227.

## Candidate shapes

akram09 pointed at one pattern for both kernels; the two kernels actually ship different shapes, so both are candidates:

- **RelationState-style wrapper** (what opensearch ships): this repo already carries the base class (`core/relation_state.py`, subclassed by `PostgreSQLPeer`/`PostgreSQLApplication`) — a client-relation sibling adds no dependencies and mirrors the sibling-kernel pattern cited in the review. akram09's own instinct points this way too (#226: "This can easily go in the state").
- **Shared dpcharmlibs typed models** (what valkey and etcd ship): pydantic request/response models from data-platform-charmlibs — maintained shared schemas instead of bespoke per-field properties, at the cost of adding the dependency.

## Design constraint any shape must respect

Provider-published fields are leader-only reads through the data-platform library and feed the per-unit `user_hash` sync check (`are_units_in_sync`, written per-unit by `managers/config.py`): an accessor exposing a merged view of both relation sides would make the hash leadership-dependent and break unit-sync. An accessor scoped to the requirer-side request payload avoids that.

## Scope

In: the requirer-side request reads in `DatabaseManager`. Out unless separately decided: provider-published fields, which stay behind the leader gate on `DatabaseProvides`.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the requirer-side request reads in DatabaseManager, then compare core/relation_state.py and the typed-model exploration in #227. Check managers/config.py, are_units_in_sync, and DatabaseProvides to preserve the leader-only boundary. Done means an agreed accessor shape exposes only the requirer-side payload without changing provider-published fields or unit-sync behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, python
Domain
databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.