Есть ли какой-либо способ не получить нулевой возврат при запросе по ключу сортировки в dynamodb с использованием nodejs и serverless framework?

#node.js #aws-lambda #amazon-dynamodb #serverless-framework

#node.js #aws-lambda #amazon-dynamodb #бессерверная среда

Вопрос:

Я запрашиваю таблицу dynamodb с ключом разделения и ключом сортировки, используя serverless framework и nodejs. Я не уверен, что использую правильный синтаксис, потому что, если y добавляет условие к ключу сортировки, я всегда получаю нулевой результат.

Я пытаюсь это:

 
//Table definition serverless.yml

resources:
  Resources:
    ConsentDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          -
            AttributeName: domain
            AttributeType: S
          -
            AttributeName: ts
            AttributeType: N
        KeySchema:
          -
            AttributeName: domain
            KeyType: HASH
          -
            AttributeName: ts
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 10
          WriteCapacityUnits: 10
        TableName: ${self:custom.tableName}


//THE QUERY

app.get("/consents/:domain/:startDate/:endDate", function (req, res) {

    const params = {
        TableName: DEV_TABLE,
        KeyConditionExpression: "#dom = :doma AND #tstamp BETWEEN :startDate AND :endDate",
        ExpressionAttributeNames: {
            "#dom": "domain",
            "#tstamp": "ts"
        },
        ExpressionAttributeValues: {
            ":doma":        req.params.domain,
            ":startDate":   req.params.startDate,
            ":endDate":     req.params.endDate
        }
    };
        console.log("PARAMS: ", params);
    dynamoDb.query(params, function(err, data){
        if (err) {
            res.status(400).json({ error: "Could not get user" });
        }
        if (data.Items) { // HERE COMES THE ERROR --> TypeError: Cannot read property 'Items' of null
            res.json(data.Items);
        } else {
            res.status(404).json({ error: "User not found" });
        }
    });
});
  

Я должен видеть некоторый вывод или даже [] (есть регистры, соответствующие запросу), но получать null и:

 
console.log --> PARAMS:  { TableName: 'table-dev',
  KeyConditionExpression: '#dom = :doma AND #tstamp BETWEEN :startDate AND :endDate',
  ExpressionAttributeNames: { '#dom': 'domain', '#tstamp': 'ts' },
  ExpressionAttributeValues: 
   { ':doma': 'url.com',
     ':startDate': '1555857529129',
     ':endDate': '1555857536819' } }

2019-04-21 17:36:21.411 ( 02:00)    c7f9720f-ea15-4e15-b508-9ffea47935dd    TypeError: Cannot read property 'Items' of null
    at Response.<anonymous> (/var/task/index.js:95:11)´´´
  

Комментарии:

1. Запишите вывод data и посмотрите, есть ли там какие-либо подсказки.

Ответ №1:

хорошо, я нашел ответ, мне пришлось разобрать строку до целого числа:

 const params = {
		TableName: DEV_TABLE,
		KeyConditionExpression: "#dom = :doma AND #tstamp BETWEEN :startDate AND :endDate",
		ExpressionAttributeNames: {
			"#dom": "domain",
			"#tstamp": "ts"
		},
		ExpressionAttributeValues: {
			":doma": 		req.params.domain,
			":startDate": 	parseInt(req.params.startDate),
			":endDate": 	parseInt(req.params.endDate)
		}
	};  

Ответ №2:

Чтобы избежать таких проблем, мне нравится использовать dynamodb-sql с открытым исходным кодом, который позволяет работать с Dynamo с использованием синтаксиса SQL

Выберите пример

 /**
     *
     * @param dynamoConfig
     * @param sql
     * @param tableName
     * @param workFlowParams
     * @returns {Promise<*>}
     */
    static async getFromCache(dynamoConfig, sql, tableName, workFlowParams) {
        //Option 1 - Try to get results from Dynamo
        try {

            let db = require('@awspilot/dynamodb-sql')(dynamoConfig)
            return await db.queryp(`select * from ${tableName} where ${tableName}Key = '${SHA256(JSON.stringify(sql)).words.join('')}'`)

        } catch (err) {
            console.log(`Failed to get from cache: ${JSON.stringify(err)}`)
            return [err, null]
        }

    }
  

Вставить пример

 static async updatePolicyLog (clientJobId, orgId, userId, policy, reason, dynamoConfig) {
        let db = require('@awspilot/dynamodb-sql')(dynamoConfig)

        let insert = `insert into ${tableId} set id = '${clientJobId ? clientJobId : shortId.generate()}',
                          orgId = ${orgId},
                          userId = ${userId},
                          createTime = '${moment(new Date()).format("YYYY-MM-DD HH:mm:ss.SSS")}'`

        let [err, data] = await db.queryp(insert)
    }