web-dev-qa-db-fra.com

Google BQ - comment insérer des données existantes dans des tableaux?

J'utilise Python pour charger les données dans les tables BigQuery. J'ai besoin de mettre à jour certaines lignes modifiées dans ces tables. Mais je n'arrivais pas à comprendre comment les mettre à jour correctement? J'en veux fonction UPSERT similaire - insérer une ligne uniquement si elle n'existe pas, sinon - mettre à jour la ligne existante.

Est-ce la bonne façon d'utiliser un champ spécial avec une somme de contrôle dans les tableaux (et de comparer la somme dans le processus de chargement)? S'il y a une bonne idée, comment résoudre ce problème avec Python? (Comme je le sais, il ne peut pas mettre à jour les données existantes)

Veuillez m'expliquer, quelle est la meilleure pratique?

7
Aleks Boev

BigQuery est par conception uniquement préféré. Cela signifie que vous feriez mieux de laisser les lignes en double de la même entité dans la table et d'écrire vos requêtes pour toujours lire la ligne la plus récente.

La mise à jour des lignes comme vous le savez dans les tables transactionnelles n'est pas possible dans BQ. Vous n'avez que 100 mises à jour par table et par jour. C'est très limité et leur objectif est totalement différent.

Étant donné que BQ est utilisé comme lac de données, vous devez simplement diffuser de nouvelles lignes chaque fois que l'utilisateur, par exemple: met à jour son profil. Vous finirez par avoir de 20 enregistre 20 lignes pour le même utilisateur. Plus tard, vous pouvez rematérialiser votre table pour avoir des lignes uniques en supprimant les données en double.

Voir la plus grande question pour la suite: BigQuery - instruction DELETE pour supprimer les doublons

10
Pentium10

BigQuery prend désormais en charge MERGE, qui peut combiner à la fois INSERT et UPDATE en une seule opération atomique, c'est-à-dire UPSERT.

En utilisant les exemples de tableaux de Mikhail, cela ressemblerait à:

MERGE merge_example.table_data T
USING merge_example.table_changes S
ON T.id = S.id
WHEN MATCHED THEN
  UPDATE SET value = s.value
WHEN NOT MATCHED THEN
  INSERT (id, value) VALUES(id, value)

enter image description here

Voir ici .

17
Graham Polley

BigQuery ne prend pas directement en charge UPSERT, mais si vous en avez vraiment besoin - vous pouvez utiliser UPDATE et INSERT l'un après l'autre pour obtenir le même résultat. Voir l'exemple simplifié ci-dessous

Supposons que vous ayez deux tableaux comme ci-dessous - celui qui contient vos données (yourproject.yourdadtaset.table_data) et un autre (yourproject.yourdadtaset.table_changes) qui contient les modifications que vous souhaitez appliquer à la première table

table_data
enter image description here

table_changes
enter image description here

Maintenant, les requêtes ci-dessous s'exécutent l'une après l'autre.

Mettre à jour la requête:

#standardSQL
UPDATE `yourproject.yourdadtaset.table_data` t
SET t.value = s.value
FROM `yourproject.yourdadtaset.table_changes` s
WHERE t.id = s.id

le résultat sera
enter image description here

Et maintenant - INSERT Query

#standardSQL
INSERT `yourproject.yourdadtaset.table_data` (id, value)
SELECT id, value
FROM `yourproject.yourdadtaset.table_changes`
WHERE NOT id IN (SELECT id FROM `yourproject.yourdadtaset.table_data`)

avec comme résultat (et nous avons terminé ici)
enter image description here

J'espère que l'exemple est simple et clair, afin que vous puissiez l'appliquer dans votre cas

12
Mikhail Berlyant

Je suis peut-être en retard pour cela, mais vous pouvez effectuer upsert dans BigQuery en utilisant Dataflow/Apache Beam. Vous pouvez effectuer un CoGroupByKey pour obtenir des valeurs partageant la clé commune à partir des deux sources de données (l'une étant la table de destination) et mettre à jour les données lues à partir de la table BQ de destination. Enfin, chargez les données en mode de chargement tronqué. J'espère que cela t'aides.

De cette façon, vous évitez toutes les limites de quota dans BigQuery et effectuez toutes les mises à jour dans Dataflow.

3
rish0097