đŸŽČ — mikrobloggeriet olorm - olorm-11 · olorm-12 · olorm-13

JSON i Postgres

Jeg bruker mye JSON (egentlig JSONB som er mer effektivt) i Postgres og det er bÄde raskt og enkelt Ä endre, men mÄ brukes med mÄte.

NÄr vi laget designverktÞyet vÄrt gikk i utgangspunktet alt av data fra frontenden og rett gjennom backenden som JSON og inn i en tabell i postgres. Det fungerte overraskende bra og gjorde at utviklingen av frontenden ikke trengte Ä stoppe opp pÄ grunn av backend-oppgaver. Det gjorde frontend (JS/React) utviklerne mer autonome uten at de trengte Ä lÊre seg alt av backenden (Rust).

Etterhvert, nÄr man begynner Ä fÄ litt data som ikke bare kan slettes kan man begynne Ä savne gode gamle database-skjemaer, spesielt nÄr det gjelder database-migreringer er det godt Ä kunne lene seg pÄ noen skjemaer.

Som nevnt har vi Rust som backend og den bestemmer hva som fÄr komme i JSON-kolonnene og ikke, det fungerer veldig bra sammen med sqlx som vi bruker til Ä gjÞre spÞrringer mot databasen. For Ä skrive JSON til databasen mÄ det ha en egen struct:

struct Image {
    name: String,
    alt: Option<String>,
}

og spĂžrringen blir derfor

let image = Image {name: "123", alt: None };
let yarn_id = 1;

sqlx::query!(r#"
    UPDATE yarn
    SET image = $1
    WHERE id = $2
"#,
sqlx::types::Json(image) as _,
yarn_id
)
.execute(db)
.await?;

Her mÄ vi wrappe image i en Json type fra sqlx.

For Ă„ hente data ut gjĂžr jeg

struct YarnQuery {
    image: sqlx::types::Json<Image>
}

sqlx::query_as!(r#"
    SELECT image as "image: sqlx::types::Json<Image>"
    FROM yarn
    WHERE id = $1
"#, yarn_id)
.fetch_one(db)
.await?;

Vi ser at sqlx trenger litt hjelp for Ä vite hvilke type det er nÄr vi setter inn JSON i as.

NÄr det gjelder performance sÄ har postgres stÞtte for Ä lage indekser pÄ verdier inne i en JSON-kolonne, uten at vi har hatt bruk for det enda.