我想使用JSON::XS
将MySQL查询的结果编码为JSON字符串。 JSON字符串需要看起来像这样
{
"database" : "dbname"
"retentionPolicy" : "mytest",
"tags" : {
"type" : "generate",
"location" : "total",
"source" : "ehz"
},
"points" : [{
"precision" : "ms",
"timestamp" : "ts1",
"name" : "power",
"values" : {
"value" : "val1"
}
}, {
"precision" : "ms",
"timestamp" : "ts2",
"name" : "power",
"values" : {
"value" : "val2"
}
}, {
"precision" : "ms",
"timestamp" : "ts3",
"name" : "power",
"values" : {
"value" : "val3"
}
}
]
}
每个点的points
元素的values
数组给我带来了巨大的麻烦。
以下是生成JSON
的代码块my %json_body = (
'database' => $db_name,
'retentionPolicy' => $retention,
'tags' => {
'source' => $metric_source,
'type' => $metric_type,
'location' => $metric_location
}
);
# loop through mysql result
while ( ($timestamp, $value) = $query->fetchrow_array() ) {
my %json_point1 = (
'name' => $series_name,
'timestamp' => ($timestamp * 1),
'precision' => "ms"
);
%json_point2 = ('value' => $value);
%json_values = (%json_point1, 'values' => \%json_point2);
push(@all_values, \%json_values);
}
$query->finish();
# Encode json
my %json_data = (%json_body, "points" => \@all_values);
$influx_json = encode_json(\%json_data);
我认为行push(@all_values, \%json_values)
是我的问题。如果我将%json_data
作为哈希引用传递,则仅保留while
循环中的最后一个值。如果我直接使用%json_values
,编码的JSON就会搞乱,因为它会丢失结构。
任何暗示都将受到赞赏。请耐心等待:这个数组和哈希引用已经让我的头脑爆炸了。
答案 0 :(得分:7)
我很确定您会遇到问题,因为您正在为%json_point
和%json_point2
使用全局范围的哈希值。
你看,它的根源是 - 你根本没有得到哈希列表。您将获得哈希引用的列表。
所以这里的问题是 - 当你将哈希的引用推送到@all_values
时 - 你每次都推送相同的引用。但是你要覆盖你引用的哈希的内容。
试试这个:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_thing;
my @all_values;
for ( 1..3 ) {
%hash_thing = ( "test" => $_ );
push ( @all_values, \%hash_thing ) ;
}
print join ( "\n", @all_values );
print Dumper \@all_values;
你会看到你有3次相同的'价值':
HASH(0x74478c)
HASH(0x74478c)
HASH(0x74478c)
所以如果你转储它,当然 - 你没有得到正确的数组 - 所以你的编码JSON也不起作用。
$VAR1 = [
{
'test' => 3
},
$VAR1->[0],
$VAR1->[0]
];
最简单的解决方法是使用my
将哈希范围限定为循环。 (如果还没有,请启用use strict;
和use warnings
。)
或者,您可以使用这样的哈希引用:
my @all_values;
my $hash_ref;
for ( 1..3 ) {
$hash_ref = { "test" => $_ };
push ( @all_values, $hash_ref ) ;
}
print @all_values;
print Dumper \@all_values;
因为$hash_ref
是标量,并且它是对匿名散列的引用,所以它可以通过值而不是引用插入到数组中。