

# 了解 Athena for Spark 中的已知问题
<a name="notebooks-spark-known-issues"></a>

本页面记录了 Athena for Apache Spark 中的一些已知问题。

## 创建表时出现非法参数异常
<a name="notebooks-spark-known-issues-illegal-argument-exception"></a>

尽管 Spark 不允许创建位置属性为空的数据库，但如果数据库是在 Spark 外部创建的，AWS Glue 中数据库的 `LOCATION` 属性可能为空。

如果您创建表并指定 `LOCATION` 字段为空的 AWS Glue 数据库，可能会出现以下异常：IllegalArgumentException: Cannot create a path from an empty string.（IllegalArgumentException：无法从空字符串创建路径。）

例如，如果 AWS Glue 中的默认数据库 `LOCATION` 字段为空，以下命令会引发异常：

```
spark.sql("create table testTable (firstName STRING)")
```

**建议的解决方法 A** – 使用 AWS Glue 向正在使用的数据库添加位置。

**向 AWS Glue 数据库添加位置**

1. 登录 AWS 管理控制台，然后打开 AWS Glue 控制台，网址为：[https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)。

1. 在导航窗格中，选择**数据库**。

1. 在数据库列表中，选择要编辑的数据库。

1. 在数据库的详细信息页面上，选择 **Edit**（编辑）。

1. 在 **Update a database**（更新数据库）页面上，在 **Location**（位置）处输入 Amazon S3 位置。

1. 选择 **Update Database**（更新数据库）。

**建议的解决方法 B** – 使用其他 AWS Glue 数据库，该数据库在 Amazon S3 中具有现有有效位置。例如，如果您有一个名为 `dbWithLocation` 的数据库，请使用命令 `spark.sql("use dbWithLocation")` 切换到该数据库。

**建议的解决方法 C** – 使用 Spark SQL 创建表时，为 `location` 指定一个值，如下例所示。

```
spark.sql("create table testTable (firstName STRING) 
       location 's3://amzn-s3-demo-bucket/'").
```

**建议的解决方法 D** – 如果您在创建表时指定了位置，但问题仍然出现，请确保您提供的 Amazon S3 路径包含尾部正斜杠。例如，以下命令会引发非法参数异常：

```
spark.sql("create table testTable (firstName STRING) 
       location 's3://amzn-s3-demo-bucket'")
```

要更正此问题，请向该位置添加尾部斜杠（例如 `'s3://amzn-s3-demo-bucket/'`）。

## 在工作组位置创建的数据库
<a name="notebooks-spark-known-issues-database-created-in-a-workgroup-location"></a>

如果您使用 `spark.sql('create database db')` 之类的命令创建数据库，但不指定数据库的位置，Athena 会在您的工作组位置创建一个子目录，并将该位置用于新创建的数据库。

## AWS Glue 默认数据库中 Hive 托管的表问题
<a name="notebooks-spark-known-issues-managed-tables"></a>

如果 AWS Glue 中默认数据库的 `Location` 属性不为空并指定 Amazon S3 中的有效位置，并且您使用 Athena for Spark 在 AWS Glue 默认数据库中创建 Hive 托管表，则数据将写入在 Athena Spark 工作组中指定的 Amazon S3 位置，而不是 AWS Glue 数据库指定的位置。

是否会出现此问题取决于 Apache Hive 如何处理其默认数据库。Apache Hive 在 Hive 仓库根位置中创建表数据，该位置可能与实际的默认数据库位置不同。

当您使用 Athena for Spark 在 AWS Glue 中的默认数据库下创建 Hive 托管表时，AWS Glue 表元数据可以指向两个不同位置。当您尝试 `INSERT` 或 `DROP TABLE` 操作时，这可能会导致意外行为。

要重现该问题，步骤如下：

1. 在 Athena for Spark 中，使用以下方法之一创建或保存 Hive 托管表：
   + SQL 语句，例如 `CREATE TABLE $tableName`
   + PySpark 命令，例如未在 Dataframe API 中指定 `path` 选项的 `df.write.mode("overwrite").saveAsTable($tableName)`。

   此时，AWS Glue 控制台可能会在 Amazon S3 中显示错误的表位置。

1. 在 Athena for Spark 中，使用 `DROP TABLE $table_name` 语句删除您创建的表。

1. 在运行 `DROP TABLE` 语句后，您会注意到 Amazon S3 中的底层文件仍然存在。

要解决该问题，可以执行下列操作之一：

**解决方案 A** - 创建 Hive 托管表时使用其他 AWS Glue 数据库。

**解决方案 B** - 为 AWS Glue 中的默认数据库指定一个空位置。然后，在默认数据库中创建托管表。

## Athena for Spark 和 Athena SQL 之间的 CSV 和 JSON 文件格式不兼容
<a name="notebooks-spark-known-issues-csv-and-json-file-format-incompatibility"></a>

由于开源 Spark 存在的已知问题，在 Athena for Spark 中根据 CSV 或 JSON 数据创建表时，可能无法从 Athena SQL 中读取该表，反之亦然。

例如，您可能使用以下方法之一在 Athena for Spark 中创建表：
+ 使用下面的 `USING csv` 语法：

  ```
  spark.sql('''CREATE EXTERNAL TABLE $tableName ( 
  $colName1 $colType1, 
  $colName2 $colType2, 
  $colName3 $colType3) 
  USING csv 
  PARTITIONED BY ($colName1) 
  LOCATION $s3_location''')
  ```
+  使用以下 [DataFrame API](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/dataframe.html) 语法：

  ```
  df.write.format('csv').saveAsTable($table_name)
  ```

由于开源 Spark 存在的已知问题，从 Athena SQL 对生成的表进行查询可能失败。

**建议的解决方案** - 尝试在 Athena for Spark 中使用 Apache Hive 语法创建表。有关更多信息，请参阅 Apache Spark 文档中的 [CREATE HIVEFORMAT TABLE](https://spark.apache.org/docs/latest/sql-ref-syntax-ddl-create-table-hiveformat.html)。