java - 如何使用 Java 为 S3 对象创建自定义文件名
问题描述
我正在使用 Spring Boot、Snowflake 和 AWS S3。
我有查询两个表并获得结果的 SQL 查询。结果我必须像 CSV 文件一样写入 S3 并获取下载 URL 作为回报。
我通过创建临时表并在将数据复制到 S3 后将其删除来做到这一点。
这是我的代码:
@Override
public void getUserTest(String userId) {
String q = "CREATE TEMPORARY TABLE \"TEST\".\"PUBLIC\".\"USER_TABLE_TEMP\" AS SELECT \"ID\", \"FIRST_NAME\", \"LAST_NAME\" from \"TEST\".\"PUBLIC\".\"USER_TABLE\"\n" +
" where \"ID\" = ?\n" +
" union all\n" +
" select \"ID\",\"ACCOUNT_NAME\", \"ACCOUNT_NUMBER\" from \"TEST\".\"PUBLIC\".\"ACCOUNT_DATA\"\n" +
" where \"ID\" = ?";
jdbcTemplate.query(q, s -> {}, userId, userId);
}
写入 S3 的方法。
@Override
public URL writeToS3() {
String q = "copy into s3://snowflake171 from \"TEST\".\"PUBLIC\".\"USER_TABLE_TEMP\" storage_integration = s3_int file_format = CSV_TEST;\n";
jdbcTemplate.query(q, s -> {});
URL url = generateURL();
String dropTable = "drop table if exists \"TEST\".\"PUBLIC\".\"USER_TABLE_TEMP\"";
jdbcTemplate.query(dropTable, s -> {});
return url;
}
生成 URL 的方法:
public URL generateURL() {
try {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
final AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new
AWSStaticCredentialsProvider(awsCreds)).withRegion(clientRegion).build();
// Set the presigned URL to expire after 2h.
java.util.Date expiration = new java.util.Date();
long expTimeMillis = Instant.now().toEpochMilli();
expTimeMillis += 1000 * 60 * 120;
expiration.setTime(expTimeMillis);
// Generate the presigned URL.
System.out.println("Generating pre-signed URL.");
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucket, objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(expiration);
URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
System.out.println("Pre-Signed URL: " + url.toString());
return url;
} catch (AmazonServiceException e) {
// The call was transmitted successfully, but Amazon S3 couldn't process
// it, so it returned an error response.
e.printStackTrace();
} catch (SdkClientException e) {
// Amazon S3 couldn't be contacted for a response, or the client
// couldn't parse the response from Amazon S3.
e.printStackTrace();
}
return null;
}
数据由userId
我发送查询。一切正常,但我生成的每个时间文件都具有相同的名称。如果我不删除 S3 中的现有文件,我将无法上传新文件。
我应该能够为不同的用户 ID 上传不同的文件。
我怎样才能做到这一点?
如何从 S3 中创建的文件中给出不同的名称?
我在文档https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html中看到了这一点,但我不知道在代码中应用的最佳方式。
有没有办法可以将 userId 添加为文件名的前缀?
解决方案
您可以在 COPY 查询中使用 userId 添加自定义对象键:
@Override
public URL writeToS3(userId) {
String q = "copy into s3://snowflake171/" + userId + " from \"TEST\".\"PUBLIC\".\"USER_TABLE_TEMP\" storage_integration = s3_int file_format = CSV_TEST;\n";
jdbcTemplate.query(q, s -> {});
推荐阅读
- html - CSS - 使用网格制作响应式方形网格
- php - SQL 表显示为空
- google-apps-script - 按下拉列表中的命名范围排序
- php - Corcel:如何在 Laravel 中的 WordPress 表之间形成多对多关系?
- python - 如何修复此 python 代码中的错误
- reactjs - 如何在 React 中渲染组件重定向?
- matrix-multiplication - 英特尔 MKL 矩阵产品 gemm 是否就地工作?
- javascript - 使用 Jimp 在 React Native 中处理 JavaScript 图像
- python - Python3 SQLAlchemy Azure 函数'_mysql'未定义
- c# - CefSharp 无法调用自定义 RequestHandler