英文:
Why is DynamoDB adding a NULL suffix to attribute names?
问题
我一直在进行一个小型项目的工作,注意到 DynamoDB 在我的两个属性名称中添加了 (NULL) 后缀。我之前没有注意到这一点,所以我认为这必须是在我的某个代码更改之后发生的。我在网上找不到关于这种行为的任何参考资料。
func InsertModel(m interface{}) error {
av, err := dynamodbattribute.MarshalMap(m)
if err != nil {
return fmt.Errorf("handlers: Got error marshalling map: %v", err)
}
input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(appTableName),
ConditionExpression: aws.String("attribute_not_exists(PK) AND attribute_not_exists(SK)"),
}
_, err = svc.PutItem(input)
if err != nil {
return fmt.Errorf("handlers: Got error calling PutItem: %v", err)
}
return nil
}
m
(用户模拟数据)的所有字段都是 string
类型:
UserModel{PK: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b", SK: "user_info", Name: "bla", ImageURI: "aaa"},
当我移除字段 "Name" 和 "ImageURI" 时,PutItem
在字段值中插入了布尔值 true
,如下所示。
在 MarshalMap 操作之后,这是 av
中的值。
- 带有填充的 "Name" 和 "ImageURI" 字段:
map[ImageURI:{
S: "aaa"
} Name:{
S: "bla"
} PK:{
S: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b"
} SK:{
S: "user_info"
}]
- 在
UserModel{PK: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b", SK: "user_info"}
中没有 "Name" 和 "ImageURI":
map[ImageURI:{
NULL: true
} Name:{
NULL: true
} PK:{
S: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b"
} SK:{
S: "user_info"
}]
我尝试从表中删除所有记录并重新插入,但行为仍然存在。此外,我对具有 int
类型属性的对象进行了相同的处理(插入具有填充和未填充的 int 属性的对象),当它未填充时,我得到 0(这是我期望的结果)。我尝试使用不同的字符串类型属性来复制这个问题,我得到相同的行为(为空时为 true),但属性名称不会带有后缀 NULL。
总之,总结一下,在我的情况下,这种行为似乎主要发生在 string
类型上,我只在属性 "Name" 和 "ImageURI" 中得到一个 NULL 后缀,但在我尝试过的其他字符串属性(以及 int 属性)上没有得到后缀 NULL。
英文:
I've been working on a toy project and noticed that dynamo added a (NULL) suffix in two of my attribute names. I had not noticed before, so I assume it must have happened after one of my code changes. I could not find any reference to this behavior online.
The script I'm running is a simple PutItem
got from the official Dynamodb documentation, where I insert a few mock users in a table.
func InsertModel(m interface{}) error {
av, err := dynamodbattribute.MarshalMap(m)
if err != nil {
return fmt.Errorf("handlers: Got error marshalling map: %v", err)
}
input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(appTableName),
ConditionExpression: aws.String("attribute_not_exists(PK) AND attribute_not_exists(SK)"),
}
_, err = svc.PutItem(input)
if err != nil {
return fmt.Errorf("handlers: Got error calling PutItem: %v", err)
}
return nil
}
m
(user mock data) has all fields type string
:
UserModel{PK: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b", SK: "user_info", Name: "bla", ImageURI: "aaa"},
When I remove the fields "Name" and "ImageURI", the PutItem
inserts a boolean true
to the field value as seen below.
Here is the value in av
after the MarshalMap operation.
- with populated "Name" and "ImageURI" fields:
map[ImageURI:{
S: "aaa"
} Name:{
S: "bla"
} PK:{
S: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b"
} SK:{
S: "user_info"
}]
- and here without "Name" and "ImageURI" as in
UserModel{PK: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b", SK: "user_info"}
map[ImageURI:{
NULL: true
} Name:{
NULL: true
} PK:{
S: "910cc6d8-b7e2-dfg6-d8d4-sh6d0e3fde6b"
} SK:{
S: "user_info"
}]
I have tried to delete all the records from the table and insert again but the behavior continues. Also, I did the same process for an int
type attribute (inserting the object with the int attribute populated and not populated) and I get 0 when it's not populated (which is what I'd expect). I tried replicating this with a different string type attribute, and I get the same behavior (true when empty), but the attribute name doesn't get the suffix NULL.
So in summary, it seems this behavior is mostly happening with type string
in my case, and I only get a NULL suffix in the attributes "Name" and "ImageURI", but not on the other string attribute I've tried (nor the int one).
答案1
得分: 1
我曾经在我的表项中的一个字段遇到了相同的问题。
对于这个字段,我使用了NameMap选项进行更新,当你想要使用一个在某些情况下被Dynamo保留的名称时,这个选项非常有用。
我只是尝试不使用NameMap选项,为我的字段指定了另一个名称,然后那个后缀就消失了。
希望我的经验能在某种程度上有所帮助。
问候
英文:
I had the same issue for one of the fields of my table items.
For that field I was doing an update using the NameMap option, useful when you want to use a name that, for some other reasons, is reserved by dynamo.
I just tried not to use the NameMap option, giving another name for my field, and that suffix disappeared.
I hope my experience could be somehow helpful.
Regards
答案2
得分: 0
Option A:
dynamodbattribute.MarshalMap
方法会在存在的情况下读取 JSON 结构标签。通过添加 omitempty
,它会在项目中排除该属性。然后,在以后读取它时,它将默认为结构中的空值。
type Foo struct {
Bar string `json:"bar,omitempty"`
}
Option B:
您可以通过创建自己的 dynamodb.AttributeValue
或在结构上实现 marshaller 接口来明确设置空结构值。例如:
item := map[string]*dynamodb.AttributeValue{
"Foo": {
S: aws.String("")
}
}
使 (NULL) 后缀消失:
在删除包含列中的 NULL 值的所有行之后,似乎需要一些时间才能从 AWS UI 中删除 (NULL) 后缀。在我测试时,大约需要 12 小时。
讨论:
继续在 GitHub 上讨论有关 null 行为的问题。
- https://github.com/aws/aws-sdk-go/pull/2419
- https://github.com/aws/aws-sdk-go/issues?q=MarshalMap+null
英文:
Option A
The dynamodbattribute.MarshalMap
method reads json struct tags if present. By adding omitempty
it will leave the attribute off of the item. Then when reading it back later, it will default to the empty value in the struct.
type Foo struct {
Bar string `json:"bar,omitempty"`
}
Option B
You can explicitly set empty struct values by either creating your own dynamodb.AttributeValue
or implement the marshaller interface on your struct. For example:
item := map[string]*dynamodb.AttributeValue{
"Foo": {
S: aws.String("")
}
}
Making the (NULL) suffix to go away
After deleting all the rows containing a NULL value in a column with the (NULL)
suffix, it seems to take some time for the suffix to go away from the AWS UI. When I tested this, it took roughly 12 hours.
Discussion
Continue the discussion of null behaviors on github.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论