【问题标题】:Dynamo DB + In put Item Request how to pass null value?Dynamodb + 在 putItem 请求中如何传递空值?
【发布时间】:2015-09-18 07:15:23
【问题描述】:

我有一个字段,我在模型中声明为字符串,如下所示:

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'),
});

在编辑模式下,当我将 Adderess 2 字段更新为 null 然后出现以下错误:

"Failed to edit property: One or more parameter values were invalid: An AttributeValue may not contain an empty string"

我知道会生成此错误,因为我将地址 2 字段更新为空,并且我想要的 地址 2 字段不是强制性的(可以传递数据或也可以将该列留空”)

【问题讨论】:

    标签: amazon-dynamodb


    【解决方案1】:

    您可以使用AttributeValue null 类型作为占位符。如果您无法更改类型,则选择一个标记值,如“ZZZZZ”或类似的值,并使其表示空字符串。或者,您的模型可能只有一个地址字段,然后,如果第二个地址行为空/空,您可以在 address1 中编码两个地址行。

    【讨论】:

    • 它已经被声明为一个字符串,我也无法使其成为“属性值 Null”是否有任何其他方法可以在数据类型与“字符串”保持相同的情况下做同样的事情,我可以做操作?
    【解决方案2】:

    最后我做对了,方法可能有些不同,但它对我有用!!!

    这是相同的代码。

    AttributeUpdates: {
                         Address2: 
                         {
                            Action: "DELETE"
                         },
                      }
    

    然后我在条件上添加值。

    if (propertyObj.address2) {
            params.AttributeUpdates.address2 = {
                Value: {
                    S: propertyObj.address2
                },
                Action: "PUT"
            }
        }
    

    衷心感谢所有帮助过我的人,干杯!!!

    【讨论】:

    【解决方案3】:

    我只是传递空值。这是我的 NodeJS 脚本,用于将数据从文件加载到 DynamoDB,我只是使用三元组来避免空字符串。

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

    【讨论】:

    • 您的答案应该是处理空字符串/值的实际解决方案。然而,我的理解是,DocumentClient.put 是允许的,PutItem 是不允许的。对于其他人,请参阅docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/…
    • 一个警告,我无法查询包含设置为 null 作为范围值的字段的 GSI。
    【解决方案4】:

    我认为最好的方法是检查字段的值是否为空,而不是将值保存在数据库中。

    当该字段为空时,我们不应将其包含在属性值映射中。

    这是我在GO语言中使用的代码sn-p

    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】:

      如果您使用的是 DynamoDB(不是 DocumentClient),您可以像这样指定空值

      const putItem: PutItemInput = {
        TableName: `${process.env.PRIMARY_TABLE}`,
        Item: {
          key: { S: ${userId}` },
          someField: { NULL: true }
        }
      }
      

      【讨论】:

        【解决方案6】:

        【讨论】:

          【解决方案7】:

          因为DynamoDB is NoSQL,你可以用完全不同的方式看待这个:

          不要尝试将“null”/空值添加到 DynamoDB 中,而是计划首先不要尝试使用“null”值添加属性本身...

          "null"-检查代码,而不是检查属性本身是否存在[按属性名称]:

          • 如果不存在,则将其解释为代码中该变量/属性状态的“null”
          • 如果存在,则它具有非空值
          • 如果尝试将现有属性从非“null”设置为“null”,只需删除该属性
          • 如果尝试将(“概念上”)“null”值设置为非“null”,请添加属性 [及其非“null”值]

          请注意我在上面的“null”上使用引号 - 我这样做是为了强调如果您使用这种通过不映射其属性本身来表示 null 的想法,那么实际上没有属性 作为“null”存在(没有属性实际上拥有一个实际“null”值)。

          *除了以这种方式捕获“空”检查本身的好处之外,该策略还有一个额外的好处,即节省[至少一些] DynamoDB 存储空间和读/写容量单位(即:on-demand pricing 将 1 个写入单元限制为 1kb 和 1 个读取单元限制为 4kb):没有存储属性来表示“null”意味着没有存储空间,否则会花费!我不是因为事实,但我猜亚马逊故意做出 AWS 架构设计选择来强制做出这样的决策/权衡:在 {no null values, no empty sets} 等事物的约束下运行,并节省原本会被占用的资源花费在他们身上。

          再一次,这一切都是可能的,因为 DynamoDB 的 NoSQL 实现 - 与 SQL 数据库不同,NoSQL 数据可以是非结构化的;特别是,在这种情况下,可以利用非结构化来包含给定 DynamoDB 表中某些文档中的属性,而 其他文档(在同一个表中) .在 SQL 数据库中做类似的事情是不可能的,因为每个 db 行必须有 all 列 - 这就是强制必须将 SQL 变量/列设置为 null 的记录,其中“没有值”是需要的(注意我在这句话中null 的不同格式;),并且不能只在该行上“不包括列/变量”。 NoSQL 的“在某些行上不包含列”的版本可以通过不包含属性来实现(它可以这样做,因为 NoSQL 是 非结构化 :)

          *尽管Amazon DynamoDB now supports empty values for non-key String and Binary attributes 这个策略仍然可以用于收益 - 这个策略至少仍然具有节省空间的巨大好处。

          *请注意,此策略也可用于表示“空集”(因为在 DynamoDB 中集必须至少有 1 个值)-不要映射 set 属性,直到它希望是非空的;)

          [这个策略可以在similar discussion for MongoDB阅读]

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-08-14
            • 1970-01-01
            • 1970-01-01
            • 2021-02-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多