100 % locale — i tuoi dati non lasciano mai il tuo browser

JSON in schema BigQuery — bq load lo accetta

Trasforma un campione JSON in un file di schema BigQuery. I campi di tutte le righe vengono uniti: il caricamento riesce al primo tentativo, non al terzo.

Istantaneo Privato Zero cookie
Indentazione

Input JSON

Output BigQuery

Che cosa fa questo strumento

Un campione JSON diventa un file di schema BigQuery — l’array di descrizioni di campo che bq load --schema si aspetta.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
[
  { "name": "id", "type": "INTEGER", "mode": "REQUIRED" },
  { "name": "firstName", "type": "STRING", "mode": "REQUIRED" },
  {
    "name": "address",
    "type": "RECORD",
    "mode": "REQUIRED",
    "fields": [{ "name": "city", "type": "STRING", "mode": "REQUIRED" }]
  }
]

I nomi dei campi tengono le chiavi JSON — BigQuery ammette lettere, cifre e trattini bassi, che è ciò che la maggior parte delle chiavi è già.

Ogni riga, non solo la prima

[{ "a": 1 }, { "a": 2, "b": "x" }]
[
  { "name": "a", "type": "INTEGER", "mode": "REQUIRED" },
  { "name": "b", "type": "STRING", "mode": "NULLABLE" }
]

Lo schema era letto dal solo primo oggetto, quindi caricare il resto del tuo stesso campione falliva con no such field: b. Ora i campi sono uniti su tutti gli oggetti, e quello che manca da qualche parte è NULLABLE — perché lo è.

Era un difetto vero, trovato scrivendo questa pagina e corretto, insieme ai due qui sotto.

Insieme ai campi si fondono anche i tipi. La stessa chiave tipizzata INTEGER su una riga e STRING su quella dopo riceve una colonna JSON: STRING rifiuterebbe il numero al caricamento. Due oggetti, invece, si fondono in un solo RECORD, e un sottocampo assente da una parte è lì NULLABLE.

Un array misto è una colonna JSON

{ "arr": [1, "x"] }
[{ "name": "arr", "type": "JSON", "mode": "NULLABLE" }]

Una colonna ripetuta ha un tipo, e [1, "x"] ne ha due. Tiparlo dal primo elemento — INTEGER REPEATED — produceva uno schema in cui il campione stesso non si carica. Il tipo JSON di BigQuery porta il valore così com’è: è ciò che ricevono gli array misti e gli array di array. Interi e decimali mescolati restano un FLOAT ripetuto, che copre entrambi.

Due supposizioni, dette

  • null diventa STRING NULLABLE. Il campione mostra una chiave e nessun tipo; STRING è una scelta, non una lettura. Se il campo è un numero, cambialo prima del primo caricamento.
  • Un array vuoto diventa STRING REPEATED. Stesso ragionamento: dentro non c’era nulla. Entrambi caricano il tuo campione senza problemi, ed entrambi meritano un secondo sguardo quando conoscerai il campo.

Caricare i tuoi dati JSON in BigQuery

Tre cose devono combaciare, e BigQuery non ne nomina nessuna con chiarezza quando non combaciano.

Un oggetto per riga. BigQuery carica JSON delimitato da ritorni a capo, non un array JSON. Se il tuo file inizia con [, non si carica — il convertitore NDJSON di qui fa esattamente questa conversione.

Lo schema in un file a parte. Salva l’array qui sopra come schema.json. Non fa parte del file di dati e non viene letto da lì.

bq load \
  --source_format=NEWLINE_DELIMITED_JSON \
  --schema=schema.json \
  mydataset.mytable \
  data.ndjson

Oppure via API. Lo stesso array va sotto schema.fields della configurazione del job di caricamento — il file e l’API prendono lo stesso contenuto.

Privato per progettazione

Tutto viene eseguito localmente nel browser con JavaScript. I tuoi dati non vengono mai caricati, quindi lo strumento è sicuro per contenuti sensibili e funziona anche offline.

Domande frequenti

Perché il mio array misto è diventato una colonna JSON?
Perché nessuna colonna ripetuta può contenerlo. `[1, "x"]` usciva come `INTEGER REPEATED`, dal primo elemento — e il caricamento di quello stesso campione falliva sul secondo. BigQuery ha un tipo `JSON` nativo che prende il valore così com’è: è ciò che riceve un array misto. Uno omogeneo resta una colonna ripetuta del suo tipo.
Perché un campo è NULLABLE se la mia prima riga ce l’ha sempre?
Perché un’altra riga non ce l’ha. Lo schema è l’unione di tutti gli oggetti del campione, e un campo assente in alcuni non può essere REQUIRED: il caricamento rifiuterebbe quelle righe. Leggere solo il primo oggetto dava uno schema che falliva sul resto con «no such field».
Come uso il file?
`bq load --source_format=NEWLINE_DELIMITED_JSON --schema=schema.json mydataset.mytable data.ndjson`. Lo schema vive in un file suo, accanto ai dati e non dentro di essi; via API, lo stesso array va sotto `schema.fields`.

Convertitori correlati