#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)
}