Есть ли способ не получить нулевой возврат при запросе по ключу сортировки в Dynamodb с использованием nodejs и безсерверной инфраструктуры? - PullRequest
0 голосов
/ 21 апреля 2019

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

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


//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" });
        }
    });
});

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


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)´´´

Ответы [ 2 ]

0 голосов
/ 22 апреля 2019

Чтобы избежать таких проблем, мне нравится использовать 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)
    }
0 голосов
/ 21 апреля 2019

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

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)
		}
	};
...