java 创建数据集时除STRING以外的Quicksight输入列类型无效

1wnzp6jl  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(129)

尝试通过从S3存储桶导入CSV在Quicksight中自动创建数据集时,我在尝试通过从Java API调用createDataSet()方法创建数据集时遇到错误:
您访问的页面不存在。物理表PrimaryTable中的输入列Year的类型无效。S3物理表允许的类型为[String](服务:亚马逊QuickSight;状态代码:400;错误代码:无效参数值异常;请求编号:84d3da22-4e4e-45e0-8bbf-9d01975206b0;代理:null)相关代码如下,第六个inputColumns.add行导致错误:

inputColumns.add(new InputColumn().withName("Column 1").withType(InputColumnDataType.STRING));
inputColumns.add(new InputColumn().withName("Column 2").withType(InputColumnDataType.STRING));
inputColumns.add(new InputColumn().withName("Column 3").withType(InputColumnDataType.STRING));
inputColumns.add(new InputColumn().withName("Column 4").withType(InputColumnDataType.STRING));
inputColumns.add(new InputColumn().withName("Column 5").withType(InputColumnDataType.STRING));
inputColumns.add(new InputColumn().withName("Year").withType(InputColumnDataType.INTEGER)); //*hits the error on this line*
... //more columns with types STRING, INTEGER, and DECIMAL

s3source.setDataSourceArn(QS_BASE_ARN + "datasource/" + sourceName);
s3source.setInputColumns(inputColumns);
uploadSettings.setFormat(FileFormat.CSV.name());
uploadSettings.setContainsHeader(true);
uploadSettings.setDelimiter(",");
s3source.setUploadSettings(uploadSettings);
physicalTable.setS3Source(s3source);
Map<String, PhysicalTable> physicalTableMap = new HashMap<String, PhysicalTable>();
physicalTableMap.put("PrimaryTable", physicalTable);
newDataSet.withAwsAccountId(ACCOUNT_ID).withDataSetId(dataSetId).withName(dataSetName).withPhysicalTableMap(physicalTableMap).withImportMode("SPICE"); //These are all the required parameters for the API request
permissions.add(new ResourcePermission().withPrincipal(QS_BASE_ARN + "user/default/" + username).withActions("quicksight:UpdateDataSetPermissions","quicksight:DescribeDataSet","quicksight:DescribeDataSetPermissions","quicksight:PassDataSet", "quicksight:DescribeIngestion", "quicksight:ListIngestions", "quicksight:UpdateDataSet", "quicksight:DeleteDataSet","quicksight:CreateIngestion","quicksight:CancelIngestion"));
newDataSet.setPermissions(permissions);
try {
   return getClient().createDataSet(newDataSet); //Creates SPICE dataset
} catch (SdkClientException e) {
   throw e;
}

getClient()方法为:

private static AmazonQuickSight getClient() {
   final AWSCredentialsProvider credsProvider = new AWSCredentialsProvider() {
   @Override
   public AWSCredentials getCredentials() {
      // provide actual IAM access key and secret key here
      return new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
   }
   @Override
   public void refresh() {}
   };
   return AmazonQuickSightClientBuilder
      .standard()
      .withRegion(Regions.US_EAST_1.getName())
      .withCredentials(credsProvider)
      .build();
}

API文档说明STRING|整数|小数位|日期时间|比特|布尔型|JSON都被接受,但是错误消息和测试表明只有STRING被接受为类型(API文档:https://docs.aws.amazon.com/quicksight/latest/APIReference/API_InputColumn.html)的数据。
这个错误是由API不接受它声称接受的数据类型引起的,还是由我的设置引起的?

zysjyyx4

zysjyyx41#

我知道我晚了18个月,但我也在这个问题上挣扎,最终找到了一个解决方案。物理表Map只是将要阅读的列Map到QuickSight中,但是(除非S3源文件是JSON),您需要创建一个LogicalTableMap来将任何列转换为所需的数据类型。我使用的是Java SDK V2,但V1非常相似。

LogicalTableSource logicalTableSource = LogicalTableSource.builder().physicalTableId("PrimaryTable").build();

ArrayList<TransformOperation> dataTransforms = dataTransforms();

LogicalTable logicalTable = LogicalTable.builder().alias("LogicalTableAlias").dataTransforms(dataTransforms)
                .source(logicalTableSource).build();
        
Map<String, LogicalTable> logicalTableMap = new HashMap<String, LogicalTable>();
        logicalTableMap.put("LogicalTableMap", logicalTable);
    CreateDataSetRequest createDataSetRequest = CreateDataSetRequest.builder()
            .awsAccountId(AwsAccountID)
            .dataSetId(dataSetId)
            .name(name)
            .physicalTableMap(physicalTableMap)
            .logicalTableMap(logicalTableMap)
            .permissions(permissions)
            .importMode(DataSetImportMode.SPICE)
            .build();

    // Create data set
    getClient().createDataSet(createDataSetRequest);

其中dataTransforms()方法为:

private static ArrayList<TransformOperation> dataTransforms() {
    ArrayList<TransformOperation> dataTransforms = new ArrayList<TransformOperation>();

    // Cast "Year" column as INTEGER
    CastColumnTypeOperation castYear = CastColumnTypeOperation.builder()
            .columnName("Year").newColumnType(ColumnDataType.INTEGER).build();
    TransformOperation yearTransform = TransformOperation.builder()
            .castColumnTypeOperation(castYear).build();
    dataTransforms.add(yearTransform);
return dataTransforms;
}

相关问题