简体   繁体   English

如何确保步骤 Function 在 AWS 中正确执行参数化查询?

[英]How to ensure a Step Function executes Parameterized Query properly in AWS?

I'm currently trying to execute an Athena Query during a State Machine.我目前正在尝试在 State 机器上执行 Athena 查询。 The query itself needs a date variable to use in several WHERE statements so I'm using a Lambda to generate it.查询本身需要一个日期变量以在多个WHERE语句中使用,因此我使用 Lambda 来生成它。

When I run EXECUTE prepared-statement USING 'date', 'date', 'date';当我运行EXECUTE prepared-statement USING 'date', 'date', 'date'; directly in Athena, I get the results I expect so I know the query is formed correctly, but when I try to do it in the state machine, it gives me the following error:直接在 Athena 中,我得到了我期望的结果,所以我知道查询是正确形成的,但是当我尝试在 state 机器上执行它时,它给了我以下错误:

SYNTAX_ERROR: line 19:37: Unexpected parameters (integer) for function date. Expected: date(varchar(x)) , date(timestamp) , date(timestamp with time zone)

So my best guess is that I'm somehow not passing the execution parameters correctly.所以我最好的猜测是我以某种方式没有正确传递执行参数。

The Lambda that calculates the date returns it in a string with the format %Y-%m-%d , and in the State Machine I make sure to pass it to the output of every State that needs it.计算日期的 Lambda 以格式%Y-%m-%d的字符串返回它,在 State 机器中,我确保将它传递给需要它的每个 State 的 output。 Then I get a named query to create a prepare statement from within the state machine.然后我得到一个命名查询,以在 state 机器中创建一个准备语句。 I then use that prepared statement to run an EXECUTE query that requires the date multiple times, so I use an intrinsic function to turn it into an array:然后我使用该准备好的语句运行多次需要日期的EXECUTE查询,因此我使用内部 function 将其转换为数组:

{
    "StartAt": "calculate_date",
    "States": {
        "calculate_date": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "Parameters": {
                "Payload.$": "$",
                "FunctionName": "arn:aws:lambda:::function:calculate_date:$LATEST"
            },
            "Retry": [
                {
                "ErrorEquals": [
                    "Lambda.ServiceException",
                    "Lambda.AWSLambdaException",
                    "Lambda.SdkClientException",
                    "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 2,
                "MaxAttempts": 6,
                "BackoffRate": 2
                }
            ],
            "Next": "get_query",
            "ResultSelector": {
                "ExecDate.$": "$.Payload.body.exec_date"
            }
        },
        "get_query": {
            "Type": "Task",
            "Next": "prepare_query",
            "Parameters": {
                "NamedQueryId": "abc123"
            },
            "Resource": "arn:aws:states:::aws-sdk:athena:getNamedQuery",
            "ResultPath": "$.Payload"
        },
        "prepare_query": {
            "Type": "Task",
            "Next": "execute_query",
            "Parameters": {
                "QueryStatement.$": "$.Payload.NamedQuery.QueryString",
                "StatementName": "PreparedStatementName",
                "WorkGroup": "athena-workgroup"
            },
            "Resource": "arn:aws:states:::aws-sdk:athena:createPreparedStatement",
            "ResultPath": "$.Payload"
        },
        "execute_query": {
            "Type": "Task",
            "Resource": "arn:aws:states:::athena:startQueryExecution",
            "Parameters": {
                "ExecutionParameters.$": "States.Array($.ExecDate, $.ExecDate, $.ExecDate)",
                "QueryExecutionContext": {
                    "Catalog": "catalog_name",
                    "Database": "database_name"
                },
                "QueryString": "EXECUTE PreparedStatementName",
                "WorkGroup": "athena-workgroup",
                "ResultConfiguration": {
                    "OutputLocation": "s3://bucket"
                }
            },
            "End": true
        }
    }
}

The execution of the State Machine returns successfully, but the query doesn't export the results to the bucket, and when I click on the "Athena query execution" link in the list of events, it takes me to the Athena editor page where I see the error listed above State 机器的执行成功返回,但查询不会将结果导出到存储桶,当我单击事件列表中的“Athena 查询执行”链接时,它会将我带到我的 Athena 编辑器页面查看上面列出的错误

https://i.stack.imgur.com/pxxOm.png https://i.stack.imgur.com/pxxOm.png

Am I generating the ExecutionParameters wrong?我是否生成了错误的ExecutionParameters Does the createPreparedStatement resource need a different syntax for the query parameters? createPreparedStatement资源是否需要不同的查询参数语法? I'm truly at a lost here, so any help is greatly appreciated我真的在这里迷路了,所以非常感谢任何帮助

I just solved my problem.我刚刚解决了我的问题。 And I'm posting this answer in case anyone comes across the same issue.如果有人遇到同样的问题,我会发布这个答案。

Apparently, the ExecutionParameters paremeter in an Athena StartQueryExecution state does not respect the variable type of a JSONPath variable, so you need to manually add the single quotes when forming your array.显然,Athena StartQueryExecution state 中的ExecutionParameters参数不遵守 JSONPath 变量的变量类型,因此您需要在形成数组时手动添加单引号。 I solved this by adding a secondary output from the lambda, with the date wrapped in single quotes so that when I make the array using instrinsic functions and pass it to the query execution, it forms the query string correctly.我通过从 lambda 添加一个辅助 output 来解决这个问题,日期用单引号引起来,这样当我使用内部函数创建数组并将其传递给查询执行时,它 forms 正确地查询字符串。

Transform the output from the lambda like this:像这样从 lambda 转换 output:

"ExecDateQuery.$": "States.Format('\\'{}\\'', $.Payload.body.exec_date)"

And use ExecDateQuery in the array intrinsic function, instead of ExecDate .并在数组内部 function 中使用ExecDateQuery而不是ExecDate

The final State Machine would look like this:最终的 State 机器看起来像这样:

{
    "StartAt": "calculate_date",
    "States": {
        "calculate_date": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "Parameters": {
                "Payload.$": "$",
                "FunctionName": "arn:aws:lambda:::function:calculate_date:$LATEST"
            },
            "Retry": [
                {
                "ErrorEquals": [
                    "Lambda.ServiceException",
                    "Lambda.AWSLambdaException",
                    "Lambda.SdkClientException",
                    "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 2,
                "MaxAttempts": 6,
                "BackoffRate": 2
                }
            ],
            "Next": "get_query",
            "ResultSelector": {
                "ExecDate.$": "$.Payload.body.exec_date",
                "ExecDateQuery.$": "States.Format('\\'{}\\'', $.Payload.body.exec_date)"
            }
        },
        "get_query": {
            "Type": "Task",
            "Next": "prepare_query",
            "Parameters": {
                "NamedQueryId": "abc123"
            },
            "Resource": "arn:aws:states:::aws-sdk:athena:getNamedQuery",
            "ResultPath": "$.Payload"
        },
        "prepare_query": {
            "Type": "Task",
            "Next": "execute_query",
            "Parameters": {
                "QueryStatement.$": "$.Payload.NamedQuery.QueryString",
                "StatementName": "PreparedStatementName",
                "WorkGroup": "athena-workgroup"
            },
            "Resource": "arn:aws:states:::aws-sdk:athena:createPreparedStatement",
            "ResultPath": "$.Payload"
        },
        "execute_query": {
            "Type": "Task",
            "Resource": "arn:aws:states:::athena:startQueryExecution",
            "Parameters": {
                "ExecutionParameters.$": "States.Array($.ExecDateQuery, $.ExecDateQuery, $.ExecDateQuery)",
                "QueryExecutionContext": {
                    "Catalog": "catalog_name",
                    "Database": "database_name"
                },
                "QueryString": "EXECUTE PreparedStatementName",
                "WorkGroup": "athena-workgroup",
                "ResultConfiguration": {
                    "OutputLocation": "s3://bucket"
                }
            },
            "End": true
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM