上传文件至 Stage
Databend 推荐两种上传文件至 Stage 的方法:PRESIGN命令与 PUT/GET 命令。这些方法可实现客户端与存储之间的直接数据传输,避免中间环节,从而减少 Databend 与存储间的流量开销,节省成本。
PRESIGN 方法会生成一个带签名且有时效的 URL,客户端可用其安全地发起文件上传。该 URL 授予临时访问指定 Stage 的权限,使得客户端无需依赖 Databend 服务器即可直接传输数据,既提升安全性又提高效率。
若使用BendSQL管理 Stage 中的文件,可通过 PUT 命令上传文件,GET 命令下载文件。
- 当前 GET 命令仅能下载 Stage 内全部文件,无法单独下载单个文件。
- 这些命令为 BendSQL 专属,当 Databend 使用文件系统作为存储后端时,GET 命令 将无法使用。
使用预签名 URL 上传
以下示例展示如何通过预签名 URL 将示例文件 (books.parquet) 上传至用户 Stage、内部 Stage 及外部 Stage。
- 上传至用户Stage
- 上传至内部Stage
- 上传至外部Stage
PRESIGN UPLOAD @~/books.parquet;
结果:
┌────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 字段名 │ 值 │
├────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ method │ PUT │
│ headers│ {"host":"s3.us-east-2.amazonaws.com"} │
│ url │ https://s3.us-east-2.amazonaws.com/databend-toronto/stage/user/root/books.parquet?X-Amz-Algorithm... │
└────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
curl -X PUT -T books.parquet "https://s3.us-east-2.amazonaws.com/databend-toronto/stage/user/root/books.parquet?X-Amz-Algorithm=... ...
检查已上传文件:
LIST @~;
结果:
┌───────────────┬──────┬──────────────────────────────────────┬─────────────────────────────────┬─────────┐
│ 文件名 │ 大小 │ md5哈希值 │ 最后修改时间 │ 创建者 │
├───────────────┼──────┼──────────────────────────────────────┼─────────────────────────────────┼─────────┤
│ books.parquet │ 998 │ 88432bf90aadb79073682988b39d461c │ 2023-06-27 16:03:51.000 +0000 │ │
└───────────────┴──────┴──────────────────────────────────────┴─────────────────────────────────┴─────────┘
CREATE STAGE my_internal_stage;
PRESIGN UPLOAD @my_internal_stage/books.parquet;
结果:
┌─────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ──────────────────────┐
│ 字段名 │ 值 │
├─────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ method │ PUT │
│ headers │ {"host":"s3.us-east-2.amazonaws.com"} │
│ url │ https://s3.us-east-2.amazonaws.com/databend-toronto/stage/internal/my_internal_stage/books.parquet?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASTQNLUZWP2UY2HSN%2F20230628%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20230628T022951Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=9cfcdf3b3554280211f88629d60358c6d6e6a5e49cd83146f1daea7dfe37f5c1 │
└─────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
curl -X PUT -T books.parquet "https://s3.us-east-2.amazonaws.com/databend-toronto/stage/internal/my_internal_stage/books.parquet?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASTQNLUZWP2UY2HSN%2F20230628%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20230628T022951Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=9cfcdf3b3554280211f88629d60358c6d6e6a5e49cd83146f1daea7dfe37f5c1"
检查已上传文件:
LIST @my_internal_stage;
结果:
┌──────────────────────────────────┬───────┬──────────────────────────────────────┬─────────────────────────────────┬─────────┐
│ 文件名 │ 大小 │ md5哈希值 │ 最后修改时间 │ 创建者 │
├──────────────────────────────────┼───────┼──────────────────────────────────────┼─────────────────────────────────┼─────────┤
│ books.parquet │ 998 │ "88432bf90aadb79073682988b39d461c" │ 2023-06-28 02:32:15.000 +0000 │ │
└──────────────────────────────────┴───────┴──────────────────────────────────────┴─────────────────────────────────┴─────────┘
CREATE STAGE my_external_stage
URL = 's3://databend'
CONNECTION = (
ENDPOINT_URL = 'http://127.0.0.1:9000',
aws_key_id = 'ROOTUSER',
aws_secret_key = 'CHANGEME123'
);
PRESIGN UPLOAD @my_external_stage/books.parquet;
结果:
┌─────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 名称 │ 值 │
├─────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 方法 │ PUT │
│ 头信息 │ {"host":"127.0.0.1:9000"} │
│ 网址 │ http://127.0.0.1:9000/databend/books.parquet?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ROOTUSER%2F20230628%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230628T040959Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=<签名...> │
└─────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```shell
curl -X PUT -T books.parquet "http://127.0.0.1:9000/databend/books.parquet?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ROOTUSER%2F20230628%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230628T040959Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=<签名...>"
检查已暂存的文件:
LIST @my_external_stage;
结果:
┌───────────────┬──────┬──────────────────────────────────────┬─────────────────────────────────┬─────────┐
│ 文件名 │ 大小 │ md5 │ 最后修改时间 │ 创建者 │
├───────────────┼──────┼──────────────────────────────────────┼─────────────────────────────────┼─────────┤
│ books.parquet │ 998 │ "88432bf90aadb79073682988b39d461c" │ 2023-06-28 04:13:15.178 +0000 │ │
└───────────────┴──────┴──────────────────────────────────────┴─────────────────────────────────┴─────────┘
使用 PUT 命令上传
以下示例展示了如何使用 BendSQL 通过 PUT 命令将示例文件(books.parquet)上传至用户级 Stage、内部 Stage 和外部 Stage。
- 上传至用户级Stage
- 上传至内部Stage
- 上传至外部Stage
PUT fs:///Users/eric/Documents/books.parquet @~
结果:
┌───────────────────────────────────────────────┐
│ 文件 │ 状态 │
├─────────────────────────────────────┼─────────┤
│ /Users/eric/Documents/books.parquet │ 成功 │
└───────────────────────────────────────────────┘
检查已暂存的文件:
LIST @~;
结果:
┌────────────────────────────────────────────────────────────────────────┐
│ 文件名 │ 大小 │ ··· │ 最后修改时间 │ 创建者 │
├───────────────┼────────┼─────┼──────────────────────┼──────────────────┤
│ books.parquet │ 998 │ ... │ 2023-09-04 03:27:... │ NULL │
└────────────────────────────────────────────────────────────────────────┘
CREATE STAGE my_internal_stage;
PUT fs:///Users/eric/Documents/books.parquet @my_internal_stage;
结果:
┌───────────────────────────────────────────────┐
│ 文 件 │ 状态 │
├─────────────────────────────────────┼─────────┤
│ /Users/eric/Documents/books.parquet │ 成功 │
└───────────────────────────────────────────────┘
检查已暂存的文件:
LIST @my_internal_stage;
结果:
┌────────────────────────────────────────────────────────────────────────┐
│ 文件名 │ 大小 │ ··· │ 最后修改时间 │ 创建者 │
├───────────────┼────────┼─────┼──────────────────────┼──────────────────┤
│ books.parquet │ 998 │ ... │ 2023-09-04 03:32:... │ NULL │
└────────────────────────────────────────────────────────────────────────┘
CREATE STAGE my_external_stage
URL = 's3://databend'
CONNECTION = (
ENDPOINT_URL = 'http://127.0.0.1:9000',
AWS_KEY_ID = 'ROOTUSER',
AWS_SECRET_KEY = 'CHANGEME123'
);
PUT fs:///Users/eric/Documents/books.parquet @my_external_stage
结果:
┌───────────────────────────────────────────────┐
│ 文件 │ 状态 │
├─────────────────────────────────────┼─────────┤
│ /Users/eric/Documents/books.parquet │ 成功 │
└───────────────────────────────────────────────┘
检查已暂存的文件:
LIST @my_external_stage;
结果:
┌──────────────────────────────────────────────────────────────────────┐
│ 文件名 │ ··· │ 最后修改时间 │ 创建者 │
├──────────────────────┼─────┼──────────────────────┼──────────────────┤
│ books.parquet │ ... │ 2023-09-04 03:37:... │ NULL │
└──── ──────────────────────────────────────────────────────────────────┘
使用 PUT 命令上传目录
您还可以使用带通配符的 PUT 命令从目录上传多个文件。这在需要一次性暂存大量文件时非常有用。
PUT fs:///home/ubuntu/datas/event_data/*.parquet @your_stage;
结果:
┌───────────────────────────────────────────────────────┐
│ 文件 │状态 │
├─────────────────────────────────────────────┼─────────┤
│ /home/ubuntu/datas/event_data/file1.parquet │ 成功 │
│ /home/ubuntu/datas/event_data/file2.parquet │ 成功 │
│ /home/ubuntu/datas/event_data/file3.parquet │ 成功 │
└────────────────────── ─────────────────────────────────┘
使用 GET 命令下载
以下示例展示了如何使用 BendSQL 通过 GET 命令从用户级 Stage、内部 Stage 和外部 Stage 下载示例文件(books.parquet)。
- 从用户级Stage下载
- 从内部Stage下载
- 从外部Stage下载
LIST @~;
结果:
┌────────────────────────────────────────────────────────────────────────┐
│ 文件名 │ 大小 │ ··· │ 最后修改时间 │ 创建者 │
├───────────────┼────────┼─────┼──────────────────────┼──────────────────┤
│ books.parquet │ 998 │ ... │ 2023-09-04 03:27:... │ NULL │
└────────────────────────────────────────────────────────────────────────┘
GET @~/ fs:///Users/eric/Downloads/fromStage/;
结果:
┌─────────────────────────────────────────────────────────┐
│ 文件 │ 状态 │
├─── ────────────────────────────────────────────┼─────────┤
│ /Users/eric/Downloads/fromStage/books.parquet │ 成功 │
└─────────────────────────────────────────────────────────┘
LIST @my_internal_stage;
结果:
┌────────────────────────────────────────────────────────────────────────┐
│ 文件名 │ 大小 │ ··· │ 最后修改时间 │ 创建者 │
├───────────────┼────────┼─────┼──────────────────────┼──────────────────┤
│ books.parquet │ 998 │ ... │ 2023-09-04 03:32:... │ NULL │
└────────────────────────────────────────────────────────────────────────┘
GET @my_internal_stage/ fs:///Users/eric/Downloads/fromStage/;
结果:
┌─────────────────────────────────────────────────────────┐
│ 文件 │ 状态 │
├───────────────────────────────────────────────┼─────────┤
│ /Users/eric/Downloads/fromStage/books.parquet │ 成功 │
└─────────────────────────────────────────────────────────┘
LIST @my_external_stage;
结果:
┌──────────────────────────────────────────────────────────────────────┐
│ 名称 │ ··· │ 最后修改时间 │ 创建者 │
├──────────────────────┼─────┼──────────────────────┼──────────────────┤
│ books.parquet │ ... │ 2023-09-04 03:37:... │ NULL │
└──────────────────────────────────────────────────────────────────────┘
GET @my_external_stage/ fs:///Users/eric/Downloads/fromStage/;