9
votes

Copier la structure de la table seule dans Bigquery

Dans la grande requête de Google, existe-t-il un moyen de cloner (copier la structure seule) une table sans données?

bq cp ne semble pas avoir d'option pour copier la structure sans données. Et Créer une table comme Select (CTAS) avec un filtre tel que "1 = 2" crée la table sans données. Mais, il ne copie pas les propriétés de partitionnement / clustering.


1 commentaires

veuillez consulter la suggestion donnée dans ce fil


5 Réponses :


2
votes

Vous pouvez utiliser l ' API de BigQuery pour exécuter une sélection, comme vous l'avez suggéré, qui retournera un résultat vide et définira les champs de partition et de cluster.

Ceci est un exemple (Seule la partition mais le cluster fonctionne également)

curl --request POST \
  'https://www.googleapis.com/bigquery/v2/projects/myProject/jobs' \
  --header 'Authorization: Bearer [YOUR_BEARER_TOKEN]' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"configuration":{"query":{"query":"SELECT * FROM `Project.dataset.audit` WHERE 1 = 2","timePartitioning":{"type":"DAY"},"destinationTable":{"datasetId":"datasetId","projectId":"projectId","tableId":"test"},"useLegacySql":false}}}' \
  --compressed
Résultat entrez la description de l'image ici


0 commentaires

15
votes

Vous pouvez utiliser DDL et limiter 0, mais vous devez également exprimer le partitionnement et le clustering dans la requête

#standardSQL
 CREATE TABLE mydataset.myclusteredtable
 PARTITION BY DATE(timestamp)
 CLUSTER BY
   customer_id
 AS SELECT * FROM mydataset.myothertable LIMIT 0


1 commentaires

Merci pour la réponse. L'inconvénient de cette approche est qu'il n'est pas possible de créer une table partitionnée par date d'ingestion à partir du résultat d'une requête.



5
votes

Si vous souhaitez cloner la structure de la table avec les propriétés de partitionnement / clustering sans avoir besoin de savoir exactement quelles propriétés de partitionnement / clustering - suivez les étapes ci-dessous:

Étape 1 : juste copiez your_table dans une nouvelle table - disons your_table_copy . Cela copiera évidemment toute la table, y compris toutes les propriétés (y compris telles que les descriptions, l'expiration de la partition, etc. - ce qui est très simple à manquer si vous essayez de les définir manuellement) et les données. Remarque: la copie est une opération gratuite

Étape 2 : pour supprimer les données de la table nouvellement créée - exécutez ci-dessous l'instruction de requête

SELECT * FROM `project.dataset.your_table_copy` LIMIT 0    

lors de l'exécution ci-dessus, assurez-vous de définir project.dataset.your_table_copy comme table de destination avec 'Overwrite Table' comme 'Write Preference'. Remarque: il s'agit également d'une étape gratuite (en raison de LIMIT 0)

Vous pouvez facilement effectuer les deux étapes ci-dessus à partir de l'interface utilisateur Web, de la ligne de commande ou de l'API ou de tout client de votre choix - tout ce qui vous convient le mieux


2 commentaires

Comment SELECTing efface-t-il les données? Je me serais attendu à SUPPRIMER.


Je vois. Vous dites que cette instruction SELECT sert de source de la copie; avec écrasement, cela signifie la suppression de la destination.



2
votes

Enfin, je suis allé avec le script python ci-dessous pour détecter les propriétés de schéma / partitionnement / clustering pour recréer (cloner) la table clusterisée sans données. J'espère que nous obtenons une fonctionnalité prête à l'emploi de bigquery pour cloner une structure de table sans avoir besoin d'un script comme celui-ci.

import commands
import json

BQ_EXPORT_SCHEMA = "bq show --schema --format=prettyjson %project%:%dataset%.%table% > %path_to_schema%"
BQ_SHOW_TABLE_DEF="bq show --format=prettyjson %project%:%dataset%.%table%"
BQ_MK_TABLE = "bq mk --table --time_partitioning_type=%partition_type% %optional_time_partition_field% --clustering_fields %clustering_fields% %project%:%dataset%.%table% ./%cluster_json_file%"


def create_table_with_cluster(bq_project, bq_dataset, source_table, target_table):

    cmd = BQ_EXPORT_SCHEMA.replace('%project%', bq_project)\
        .replace('%dataset%', bq_dataset)\
        .replace('%table%', source_table)\
        .replace('%path_to_schema%', source_table)
    commands.getstatusoutput(cmd)

    cmd = BQ_SHOW_TABLE_DEF.replace('%project%', bq_project)\
        .replace('%dataset%', bq_dataset)\
        .replace('%table%', source_table)
    (return_value, output) = commands.getstatusoutput(cmd)

    bq_result = json.loads(output)

    clustering_fields = bq_result["clustering"]["fields"]
    time_partitioning = bq_result["timePartitioning"]
    time_partitioning_type = time_partitioning["type"]
    time_partitioning_field = ""
    if "field" in time_partitioning:
        time_partitioning_field = "--time_partitioning_field " + time_partitioning["field"]

    clustering_fields_list = ",".join(str(x) for x in clustering_fields)

    cmd = BQ_MK_TABLE.replace('%project%', bq_project)\
        .replace('%dataset%', bq_dataset)\
        .replace('%table%', target_table)\
        .replace('%cluster_json_file%', source_table)\
        .replace('%clustering_fields%', clustering_fields_list)\
        .replace('%partition_type%', time_partitioning_type)\
        .replace('%optional_time_partition_field%', time_partitioning_field)
    commands.getstatusoutput(cmd)


create_table_with_cluster('test_project', 'test_dataset', 'source_table', 'target_table')


0 commentaires

4
votes

Ceci est possible avec la CLI BQ.

Commencez par télécharger le schéma de la table existante:

bq mk \
  --time_partitioning_type=DAY \
  --time_partitioning_field date_field \
  --require_partition_filter \
  --table dataset.tablename \
  table.json

Ensuite, créez une nouvelle table avec le schéma fourni et requis partitionnement:

bq show --format=prettyjson project:dataset.table | jq '.schema.fields' > table.json

Pour plus d'informations sur les options bq mk : https://cloud.google.com/bigquery/docs/tables

Installez jq avec: npm install node-jq


0 commentaires