可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have one field which i have declared as string in the model as show below:
App.Student= DS.Model.extend({
name: DS.attr('string'),
address1: DS.attr('string'),
address2: DS.attr('string'),
city: DS.attr('string'),
state: DS.attr('string'),
postal: DS.attr('string'),
country: DS.attr('string'),
});
Here in the Edit mode when i update Adderess 2 field as null then below error comes:
"Failed to edit property: One or more parameter values were invalid: An AttributeValue may not contain an empty string"
I know this Error is generated because i am updating address 2 field as null and that what i want Address 2 field is not mandatory(One can pass data or can also left that column as blank")
回答1:
Finally i got this right, The way might be some what different but it work for me !!!
Here is the code for the same.
AttributeUpdates: {
Address2:
{
Action: "DELETE"
},
}
And then i am adding the value on the condition.
if (propertyObj.address2) {
params.AttributeUpdates.address2 = {
Value: {
S: propertyObj.address2
},
Action: "PUT"
}
}
Thank you to all from bottom of my heart :)who tried to help me, Cheers !!!
回答2:
I just pass nulls. Here's my NodeJS script for loading data from file into DynamoDB, I just use ternaries to avoid empty strings.
var AWS = require("aws-sdk");
var fs = require('fs');
// Make sure we got a filename on the command line.
if (process.argv.length < 3) {
console.log('Usage: node ' + process.argv[1] + ' FILENAME');
process.exit(1);
}
var filename = process.argv[2];
AWS.config.update({
region: "us-west-2",
//endpoint: "http://localhost:8000"
});
var docClient = new AWS.DynamoDB.DocumentClient();
console.log("Importing Addresses into DynamoDB. Please wait.");
var allObjs = JSON.parse(fs.readFileSync(filename, 'utf8'));
allObjs.forEach(function(obj) {
var params = {
TableName: "Address",
Item: {
"address_detail_pid": obj.address_detail_pid,
"flat_type": obj.flat_type == '' ? null : obj.flat_type,
"flat_number": obj.flat_number == '' ? null : obj.flat_number,
"level_type": obj.level_type == '' ? null : obj.level_type,
"level_number": obj.level_number == '' ? null : obj.level_number,
"number_first": obj.number_first == '' ? null : obj.number_first,
"street_name": obj.street_name == '' ? null : obj.street_name,
"street_type_code": obj.street_type_code == '' ? null : obj.street_type_code,
"locality_name": obj.locality_name == '' ? null : obj.locality_name,
"state_abbreviation": obj.state_abbreviation == '' ? null : obj.state_abbreviation,
"postcode": obj.postcode == '' ? null : obj.postcode,
"longitude": obj.longitude == '' ? null : obj.longitude,
"latitude": obj.latitude == '' ? null : obj.latitude
}
};
docClient.put(params, function(err, data) {
if (err) {
console.error("Unable to add obj", obj.address_detail_pid, ". Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("PutItem succeeded:", obj.address_detail_pid);
}
});
});
回答3:
You can use AttributeValue null type as a placeholder. If you cannot change the type, then, choose a sentinel value, like "ZZZZZ" or similar and make that represent the empty string. Alternatively, your model could just have one address field, and then, you could encode both address lines in address1, if the second address line is null/empty.
回答4:
I think the best way is to check if the value of the field is blank and not save the value in the database.
When the field is blank, we should not include it in the attribute value map.
Here is the code snippet I have used in GO language
myAttributeValues := map[string]*dynamodb.AttributeValue{
“field1”: {
S: aws.String(value1),
},
“field2”: {
S: aws.String(value2),
},
“field3”: {
S: aws.String(value3),
},
}
if field4 != "" {
field4Attribute := dynamodb.AttributeValue{
S: aws.String(value4),
}
myAttributeValues[“field4”] = &field4Attribute
}
if field5 != "" {
field5Attribute := dynamodb.AttributeValue{
S: aws.String(value5),
}
myAttributeValues["field5"] = &field5Attribute
}
input := &dynamodb.PutItemInput{
TableName: aws.String(mytableName),
Item: myAttributeValues,
}
回答5:
If you are using DynamoDB (not DocumentClient) you can specify nulls like this
const putItem: PutItemInput = {
TableName: `${process.env.PRIMARY_TABLE}`,
Item: {
key: { S: ${userId}` },
someField: { NULL: true }
}
}
回答6:
AWS finally resolved this issue.
DynamoDb now supports empty string values for non-key attributes: https://aws.amazon.com/about-aws/whats-new/2020/05/amazon-dynamodb-now-supports-empty-values-for-non-key-string-and-binary-attributes-in-dynamodb-tables/
回答7:
Since DynamoDB is NoSQL, you can look at this in an entirely different way:
Instead of trying to add a "null"/empty value into DynamoDB, just plan on not attempting to add the attribute itself with the "null" value in the first place...
"null"-check in code, instead by checking if the attribute itself is present [by attribute name]:
- If not present, interpret that as "null" for the state of that variable/attribute in code
- If present, then it has a non-null value
- If trying to set an existing attribute from non-"null" to "null", just remove the attribute
- If trying to set what is ("conceptually" at the moment) a "null" value to non-"null", add the attribute [with its non-"null" value]
Note my use of quotes on "null" above - I did that on purpose to emphasize that if you use this thinking of representing null by not mapping its attribute itself, then there is no attribute that actually exists as "null" (no attribute that actually holds an actual "null" value).
*Besides the benefit of capturing "null"-checking in this way being possible in itself, this strategy has an additional benefit of saving [at least some] DynamoDB storage space, & read/write capacity units (i.e: on-demand pricing limits 1 write unit to 1kb & 1 read unit to 4kb): No attribute stored to represent "null" means no storage otherwise spent! I don't for a fact, but I am guessing Amazon intentionally makes AWS architecture design choices to force decisions/tradeoffs like this: Operate under constraint of things like {no null values, no empty sets}, and save resources that would otherwise be spent on them.
Once again, this is all possible because of DynamoDB's NoSQL implementation - unlike a SQL database, NoSQL data can be unstructured; and in particular, the unstructured-ness can be leveraged in this case to include an attribute in some documents in a given DynamoDB table and not other documents (in the same table). It is impossible to do the analogous same thing in a SQL database as each db row there must have all columns - that's what forces having to set a SQL variable/column to null
for records where "no value" is desired (note my different formatting of null
in this sentence ;), and not being able to just "not include the column/variable" on that row. NoSQL's version to "not include a column on some rows" is possible by just not including an attribute (which it can do because NoSQL is unstructured :)
*This strategy can still be used for benefits despite the fact that Amazon DynamoDB now supports empty values for non-key String and Binary attributes - this strategy would still at least have the exceeding benefit of saving space.
*Note this strategy can also be used to represent an "empty set" (since in DynamoDB sets must have at least 1 value) - just don't map the set attribute until it is desired to be non-empty ;)
[This strategy can be read in a similar discussion for MongoDB]