首页 > 解决方案 > 在 Airflow 中使用 Sqoop 运算符在 HIVE 表中使用“//N”空字符串参数导致“/N”字符串值

问题描述

我正在尝试使用 sqoop 使用 Airflow Sqoop Operator 传输一些数据。此数据包含空值,我希望它们NULL在我的 HIVE 表中结束。

sqoop_operator_task = SqoopOperator(
    task_id = table[0],
    conn_id = "JDBC_OPA",
    table = table_name,
    cmd_type = "import",
    target_dir = "/sourcedata/sqoop_tmp/"+table_name,
    num_mappers = 1,
    extra_import_options = {
        'delete-target-dir' : "",
        'fields-terminated-by' : r'"\001"',
        'hive-database' : database_name,
        'hive-table' : table[0],
        'hive-delims-replacement' : "' '",
        'hive-import' : "",
        'hive-overwrite' : "",
        'null-non-string' : r"'\\N'",
        'null-string' : r"'\\N'"
    },
    dag = dag
)

使用r"'\\N'"null-non-string & null-string 会导致从 Airflow 日志中获取以下命令:

sqoop import --username SELECT_OPA_DSC --password MASKED --num-mappers 1 --connect MASKED --target-dir /sourcedata/sqoop_tmp/OWNER_DMK.DMK_AVY --as-textfile --delete-target-dir --fields-terminated-by "\001" --hive-database test_db --hive-table DMK_AVY --hive-delims-replacement ' ' --hive-import --hive-overwrite --null-non-string '\\N' --null-string '\\N' --table OWNER_DMK.DMK_AVY

这是根据Sqoop 文档如何将其格式化为以NULL. 但是,我的表中最终出现了 '\N' 。然而,直接在 shell 中执行完整的命令,确实给了我NULLHIVE 表中的正确值。

我想问题在于 Sqoop 作业产生的 HIVE 查询的不同。从 Airflow 执行命令时的 HIVE 查询:

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\\001' LINES TERMINATED BY '\\012' STORED AS TEXTFILE

直接从 Shell 执行命令时的 HIVE 查询:

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001' LINES TERMINATED BY '\012' STORED AS TEXTFILE

请在一个场景上给我建议,改变我的 sqoop 运算符,以便在 Airflow 中生成的 HIVE 查询与直接使用 Shell 中的命令相同,从而NULL在 HIVE 表中产生结果。仅删除一个反斜杠是行不通的。

有关 sqoop 运算符的更多信息,请点击此处

标签: pythonshellhiveairflowsqoop

解决方案


我找到了解决方案。通过:

        'null-non-string' : r'\\N',
        'null-string' : r'\\N'

最终在命令中传递参数--null-non-string \\N并最终在 HIVE 中给出 NULL 结果。但是,直接在 shell 中传递这样的参数会引发非法转义字符错误......因此,在 shell 中处理命令的方式有所不同。


推荐阅读