简体   繁体   中英

AWS Lambda function handler not inserting to Athena

I'm using a snippet example for Amazon Athena just to test inserting some data. I can't tell why it isn't working and CloudWatch logs does not show any output when the statement execution is completed. Even when I change it to a simple select statement I can't see any output. I know the query, database and table is fine, because when I test it using the Athena query editor it executes without a problem.

module.exports.dlr = async event => {

  let awsFileCreds = {
    accessKeyId: "XXX",
    secretAccessKey: "XXX"
  };

  let creds = new AWS.Credentials(awsFileCreds);
  AWS.config.credentials = creds;

  let client = new AWS.Athena({ region: "eu-west-1" });

  let q = Queue((id, cb) => {
    startPolling(id)
      .then(data => {
        return cb(null, data);
      })
      .catch(err => {
        console.log("Failed to poll query: ", err);
        return cb(err);
      });
  }, 5);

    const sql = "INSERT INTO delivery_receipts (status, eventid, mcc, mnc, msgcount, msisdn, received, userreference) VALUES ('TestDLR', 345345, 4353, '5345435', 234, '345754', 234, '8833')"

  makeQuery(sql)
    .then(data => {
      console.log("Row Count: ", data.length);
      console.log("DATA: ", data);
    })
    .catch(e => {
      console.log("ERROR: ", e);
    });

  function makeQuery(sql) {
    return new Promise((resolve, reject) => {
      let params = {
        QueryString: sql,
        ResultConfiguration: { OutputLocation: ATHENA_OUTPUT_LOCATION },
        QueryExecutionContext: { Database: ATHENA_DB }
      };

      client.startQueryExecution(params, (err, results) => {
        if (err) return reject(err);
        q.push(results.QueryExecutionId, (err, qid) => {
          if (err) return reject(err);
          return buildResults(qid)
            .then(data => {
              return resolve(data);
            })
            .catch(err => {
              return reject(err);
            });
        });
      });
    });
  }

  function buildResults(query_id, max, page) {
    let max_num_results = max ? max : RESULT_SIZE;
    let page_token = page ? page : undefined;
    return new Promise((resolve, reject) => {
      let params = {
        QueryExecutionId: query_id,
        MaxResults: max_num_results,
        NextToken: page_token
      };

      let dataBlob = [];
      go(params);

      function go(param) {
        getResults(param)
          .then(res => {
            dataBlob = _.concat(dataBlob, res.list);
            if (res.next) {
              param.NextToken = res.next;
              return go(param);
            } else return resolve(dataBlob);
          })
          .catch(err => {
            return reject(err);
          });
      }

      function getResults() {
        return new Promise((resolve, reject) => {
          client.getQueryResults(params, (err, data) => {
            if (err) return reject(err);
            var list = [];
            let header = buildHeader(
              data.ResultSet.ResultSetMetadata.ColumnInfo
            );
            let top_row = _.map(_.head(data.ResultSet.Rows).Data, n => {
              return n.VarCharValue;
            });
            let resultSet =
              _.difference(header, top_row).length > 0
                ? data.ResultSet.Rows
                : _.drop(data.ResultSet.Rows);
            resultSet.forEach(item => {
              list.push(
                _.zipObject(
                  header,
                  _.map(item.Data, n => {
                    return n.VarCharValue;
                  })
                )
              );
            });
            return resolve({
              next: "NextToken" in data ? data.NextToken : undefined,
              list: list
            });
          });
        });
      }
    });
  }

  function startPolling(id) {
    return new Promise((resolve, reject) => {
      function poll(id) {
        client.getQueryExecution({ QueryExecutionId: id }, (err, data) => {
          if (err) return reject(err);
          if (data.QueryExecution.Status.State === "SUCCEEDED")
            return resolve(id);
          else if (
            ["FAILED", "CANCELLED"].includes(data.QueryExecution.Status.State)
          )
            return reject(
              new Error(`Query ${data.QueryExecution.Status.State}`)
            );
          else {
            setTimeout(poll, POLL_INTERVAL, id);
          }
        });
      }
      poll(id);
    });
  }

  function buildHeader(columns) {
    return _.map(columns, i => {
      return i.Name;
    });
  }

  return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

Figured it out. Using aws lambda events with athena is easy using the athena-express package. You can specify your configuration and query the athena database like you normally would with significantly less code than what's provided in the amazon athena nodejs example.

This is the code I used to achieve a result:

"use strict";

const AthenaExpress = require("athena-express"),
    aws = require("aws-sdk");

const athenaExpressConfig = {
    aws,
    db: "messaging",
    getStats: true
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);

exports.handler = async event => {
    const sqlQuery = "SELECT * FROM delivery_receipts LIMIT 3";

    try {
        let results = await athenaExpress.query(sqlQuery);
        return results;
    } catch (error) {
        return error;
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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