BigQuery:(备份)分片副本 Google Analytics 表
BigQuery: (backup) copy of sharded Google Analytics tables
当 Google Analytics 导出到 BigQuery 时,数据被放入所谓的分片表中,每天一个。它们都以 ga_sessions_
开头,后跟日期后缀。
我想备份这些分片表。
我该怎么做?
此答案与在 BQ 中创建备份有关:
所以像ga_sessions_
这样的分片table基本上存在很多tables,每天一个。我们需要分别复制所有这些 table。
以下答案是从下面的文章中复制的,所有尊重都归于作者:
https://medium.com/@Nayana22/playing-with-sharded-tables-in-bigquery-123e1ec5e453
所以你可以这样做:
- 通过点击下面的 SQL 命令获取您希望复制的所有日期的列表。 [您可以根据需要修改]
SELECT
REPLACE(STRING_AGG(CONCAT('"', partition_name,'"') ORDER BY partition_name ), ","," ")
FROM
(
SELECT
DISTINCT date AS partition_name
FROM
`[Project_ID].[DATASET_NAME].ga_sessions_*`
ORDER BY PARSE_DATE(“%Y%m%d”, date)
)
Output:
"20180322" "20180323" "20180324" "20180325" "20180326" "20180327"...
现在,转到 google 控制台,select 项目并单击激活云 Shell。
使用echo $DEVSHELL_PROJECT_ID检查当前项目。如果您在一个不正确的项目中,请更改它并转到第 4 步。
创建一个 bash 脚本并指定您刚刚从上述查询中获得的日期。
tables=(“20180322” “20180323” “20180324” “20180325” “20180326” “20180327”…)
- 遍历 tables 变量中可用的所有日期,并使用 BigQuery 的复制命令将 table 从源移动到目标。
语法:[注意:源和目标table名称之间有一个space]
bq cp -a source_table destination_table
- 我们的脚本文件如下所示:
tables=("20180322" "20180323" "20180324" "20180325" "20180326" "20180327"…)
for val in ${tables[*]}; do
bq cp -a [source_dataset].ga_sessions_$val [destination_dataset].ga_sessions_backup_$val
done
- 如何验证是否所有table都被复制了?
WITH first_ga_session AS (
SELECT MIN(PARSE_DATE("%Y%m%d", REGEXP_EXTRACT(table_id, '20[0–9]
{6,6}'))) AS day
FROM `[PROJECT_ID].[DATASET_NAME].__TABLES__` AS ga_tables
WHERE table_id LIKE 'ga_sessions_backup_2%'
),
all_days AS (
SELECT period
FROM
UNNEST(GENERATE_DATE_ARRAY((SELECT day from first_ga_session),
CURRENT_DATE())) AS period
),
available_ga_sessions AS (
SELECT PARSE_DATE("%Y%m%d", REGEXP_EXTRACT(table_id, '20[0–9]
{6,6}')) AS ga_day
FROM `[PROJECT_ID].[DATASET_NAME].__TABLES__` AS ga_tables
WHERE table_id LIKE 'ga_sessions_backup_2%'
)
SELECT A.period AS Day, B.ga_day AS Available_session
FROM all_days A
LEFT JOIN available_ga_sessions B
ON A.period = B.ga_day
WHERE B.ga_day IS NULL
以上查询将为我们提供目的地中缺少的所有日期 table。
我的 bash 脚本最终看起来像这样(注意我正在使用带有标志 --clone
:
的克隆
tables=("20220331" "20220401")
bq --location=eu mk --dataset destination_project_id:destination_dataset
for val in ${tables[*]}; do
echo source_project_id:source_dataset.ga_sessions_$val
bq cp --clone source_project_id:source_dataset.ga_sessions_$val destination_project_id:destination_dataset.ga_sessions_backup_$val
done
如果您想将 table 备份到云存储桶,您可以尝试以下操作。
- 查询 table meta data 以获取要导出的 table。
SELECT
table_name
FROM
`MyDataSet.INFORMATION_SCHEMA.TABLES`
WHERE
table_name LIKE 'ga_sessions_%'
- 使用 BigQuery export function 导出到存储桶。
-- If the tables are nested use json/avro/parquet
-- But be aware of the data type converstions:
-- https://cloud.google.com/bigquery/docs/exporting-data#exporting_data_stored_in
EXPORT DATA OPTIONS(
uri='gs://bucket/folder/ga_sessions_<date>_*.json',
format='JSON',
overwrite=true,
header=true,
field_delimiter=';') AS
SELECT * FROM mydataset.ga_sessions_<date>
- 把它放在一个BQ script with a loop, using FORMAT to create the query and EXECUTE IMMEDIATE到运行的查询中。
BEGIN
DECLARE backup_date STRING DEFAULT CAST(CURRENT_DATE('UTC') AS STRING);
FOR record IN
(
SELECT
table_name
FROM
`MyDataSet.INFORMATION_SCHEMA.TABLES`
WHERE
table_name LIKE 'ga_sessions_%')
DO
EXECUTE IMMEDIATE
FORMAT("""
EXPORT DATA
OPTIONS(
uri=CONCAT('gs://your_backup_bucket/path/to/folder/', '%s','/', '%s','_*.json'),
format='JSON',
overwrite=true,
header=true,
field_delimiter=';')
AS SELECT * FROM my_project.my_data_set.%s
"""
, backup_date, record.table_name, record.table_name);
END FOR;
END;
backup_date
用于创建一个 'folder',其中导出日期作为 table 存储桶中的名称。
- URI 中的
*
允许将一个 table 导出到多个 table。这仅在导出的 table 大于 1GB (See here) 时才重要
- 在您的存储桶上设置生命周期规则以在适当的时间后存档文件,或者如果仅用于备份目的则将其设置为默认存档(每年访问次数较少,请参阅storage classes)。
Tim Lou 关于 this article 使用 table 元数据的建议。
当 Google Analytics 导出到 BigQuery 时,数据被放入所谓的分片表中,每天一个。它们都以 ga_sessions_
开头,后跟日期后缀。
我想备份这些分片表。
我该怎么做?
此答案与在 BQ 中创建备份有关:
所以像ga_sessions_
这样的分片table基本上存在很多tables,每天一个。我们需要分别复制所有这些 table。
以下答案是从下面的文章中复制的,所有尊重都归于作者:
https://medium.com/@Nayana22/playing-with-sharded-tables-in-bigquery-123e1ec5e453
所以你可以这样做:
- 通过点击下面的 SQL 命令获取您希望复制的所有日期的列表。 [您可以根据需要修改]
SELECT
REPLACE(STRING_AGG(CONCAT('"', partition_name,'"') ORDER BY partition_name ), ","," ")
FROM
(
SELECT
DISTINCT date AS partition_name
FROM
`[Project_ID].[DATASET_NAME].ga_sessions_*`
ORDER BY PARSE_DATE(“%Y%m%d”, date)
)
Output:
"20180322" "20180323" "20180324" "20180325" "20180326" "20180327"...
现在,转到 google 控制台,select 项目并单击激活云 Shell。
使用echo $DEVSHELL_PROJECT_ID检查当前项目。如果您在一个不正确的项目中,请更改它并转到第 4 步。
创建一个 bash 脚本并指定您刚刚从上述查询中获得的日期。
tables=(“20180322” “20180323” “20180324” “20180325” “20180326” “20180327”…)
- 遍历 tables 变量中可用的所有日期,并使用 BigQuery 的复制命令将 table 从源移动到目标。 语法:[注意:源和目标table名称之间有一个space]
bq cp -a source_table destination_table
- 我们的脚本文件如下所示:
tables=("20180322" "20180323" "20180324" "20180325" "20180326" "20180327"…)
for val in ${tables[*]}; do
bq cp -a [source_dataset].ga_sessions_$val [destination_dataset].ga_sessions_backup_$val
done
- 如何验证是否所有table都被复制了?
WITH first_ga_session AS (
SELECT MIN(PARSE_DATE("%Y%m%d", REGEXP_EXTRACT(table_id, '20[0–9]
{6,6}'))) AS day
FROM `[PROJECT_ID].[DATASET_NAME].__TABLES__` AS ga_tables
WHERE table_id LIKE 'ga_sessions_backup_2%'
),
all_days AS (
SELECT period
FROM
UNNEST(GENERATE_DATE_ARRAY((SELECT day from first_ga_session),
CURRENT_DATE())) AS period
),
available_ga_sessions AS (
SELECT PARSE_DATE("%Y%m%d", REGEXP_EXTRACT(table_id, '20[0–9]
{6,6}')) AS ga_day
FROM `[PROJECT_ID].[DATASET_NAME].__TABLES__` AS ga_tables
WHERE table_id LIKE 'ga_sessions_backup_2%'
)
SELECT A.period AS Day, B.ga_day AS Available_session
FROM all_days A
LEFT JOIN available_ga_sessions B
ON A.period = B.ga_day
WHERE B.ga_day IS NULL
以上查询将为我们提供目的地中缺少的所有日期 table。
我的 bash 脚本最终看起来像这样(注意我正在使用带有标志 --clone
:
tables=("20220331" "20220401")
bq --location=eu mk --dataset destination_project_id:destination_dataset
for val in ${tables[*]}; do
echo source_project_id:source_dataset.ga_sessions_$val
bq cp --clone source_project_id:source_dataset.ga_sessions_$val destination_project_id:destination_dataset.ga_sessions_backup_$val
done
如果您想将 table 备份到云存储桶,您可以尝试以下操作。
- 查询 table meta data 以获取要导出的 table。
SELECT
table_name
FROM
`MyDataSet.INFORMATION_SCHEMA.TABLES`
WHERE
table_name LIKE 'ga_sessions_%'
- 使用 BigQuery export function 导出到存储桶。
-- If the tables are nested use json/avro/parquet
-- But be aware of the data type converstions:
-- https://cloud.google.com/bigquery/docs/exporting-data#exporting_data_stored_in
EXPORT DATA OPTIONS(
uri='gs://bucket/folder/ga_sessions_<date>_*.json',
format='JSON',
overwrite=true,
header=true,
field_delimiter=';') AS
SELECT * FROM mydataset.ga_sessions_<date>
- 把它放在一个BQ script with a loop, using FORMAT to create the query and EXECUTE IMMEDIATE到运行的查询中。
BEGIN
DECLARE backup_date STRING DEFAULT CAST(CURRENT_DATE('UTC') AS STRING);
FOR record IN
(
SELECT
table_name
FROM
`MyDataSet.INFORMATION_SCHEMA.TABLES`
WHERE
table_name LIKE 'ga_sessions_%')
DO
EXECUTE IMMEDIATE
FORMAT("""
EXPORT DATA
OPTIONS(
uri=CONCAT('gs://your_backup_bucket/path/to/folder/', '%s','/', '%s','_*.json'),
format='JSON',
overwrite=true,
header=true,
field_delimiter=';')
AS SELECT * FROM my_project.my_data_set.%s
"""
, backup_date, record.table_name, record.table_name);
END FOR;
END;
backup_date
用于创建一个 'folder',其中导出日期作为 table 存储桶中的名称。- URI 中的
*
允许将一个 table 导出到多个 table。这仅在导出的 table 大于 1GB (See here) 时才重要
- 在您的存储桶上设置生命周期规则以在适当的时间后存档文件,或者如果仅用于备份目的则将其设置为默认存档(每年访问次数较少,请参阅storage classes)。
Tim Lou 关于 this article 使用 table 元数据的建议。