我开发了一个Perl脚本,该脚本可以将数据格式化为CSV格式,并希望将数据保存到Postgres数据库表中。
我following this tutorial作为如何与Postgres交互的指南。我在PPM中验证是否已安装与本教程相同的版本:1.634版本的DBI和3.5.3版本的DBD :: Pg安装在Windows 10 x64的Perl 5.22.1中。该数据库是Windows Server 2008r2上的Postgres 12。
Perl脚本的第一部分读取,解析和格式化一个数据记录为CSV。这是一个CSV数据记录的示例:
"2020-05-10 20:39:16+0","0.528239011764526","15:39 05/10/2020","0x1c","LOW STATUS","0x85","Normal","73.8","32","29.11","29.31","61.2","29","80","0.7","2.5","22.6","378.64","3009","7","0.00","0.00","0.97","0.97","11.96"
这在下面输入数据库接口片段之前存储在$ SQLstring中:这是我从教程中修改的代码,该代码可以编译并运行而不会出现错误。
# ------------- Postgres Database Connection --------------
# Connection config
my $dbname = 'MyDatabase';
my $host = '192.168.1.1';
my $port = 5432;
my $username = 'myuser';
my $password = 'mypassword';
# Create DB handle object by connecting
my $dbh = DBI -> connect("dbi:Pg:dbname=$dbname;host=$host;port=$port",
$username,
$password,
{AutoCommit => 0, RaiseError => 1}
) or die $DBI::errstr;
# Trace to a file
$dbh -> trace(1, 'tracelog.txt');
# Copy from STDIN into the table
my $SQL = "COPY AmbientWeather (
datetimestamp ,
CurrTime ,
IndoorID ,
inBattSta ,
Outdoor1ID ,
outBattSta1 ,
inTemp ,
inHumi ,
AbsPress ,
RelPress ,
outTemp ,
outHumi ,
windir ,
avgwind ,
gustspeed ,
dailygust ,
solarrad ,
uv ,
uvi ,
rainofhourly ,
rainofdaily ,
rainofweekly ,
rainofmonthly ,
rainofyearly
)
FROM STDIN WITH DELIMITER ',' CSV HEADER";
my $sth = $dbh->do($SQL);
# putcopy data from saved line in CSV format
$dbh->pg_putcopydata($SQLstring);
$dbh->pg_putcopyend(); # finished with one line
$dbh->commit or die $DBI::errstr;
exit;
此程序运行无误,但数据库未更改。没有记录创建。
这是跟踪日志,它没有显示任何明显的错误,但是我对语法不是很熟悉:
DBI::db=HASH(0x3c62268) trace level set to 0x0/1 (DBI @ 0x0/0) in DBI 1.634-ithread (pid 19436)
<- DESTROY(DBI::db=HASH(0x3c62268))= ( undef ) [1 items] at Ambient_Parser.pl line 158
DBI::db=HASH(0x3c76ca8) trace level set to 0x0/1 (DBI @ 0x0/0) in DBI 1.634-ithread (pid 2108)
<- do('COPY AmbientWeather (
datetimestamp ,
CurrTime ,
IndoorID ,
inBattSta ,
Outdoor1ID ,
outBattSta1 ,
inTemp ,
inHumi ,
AbsPress ,
RelPress ,
outTemp ,
outHumi ,
windir ,
avgwind ,
gustspeed ,
dailygust ,
solarrad ,
uv ,
uvi ,
rainofhourly ,
rainofdaily ,
rainofweekly ,
rainofmonthly ,
rainofyearly
...')= ( -1 ) [1 items] at Ambient_Parser.pl line 177
<- pg_putcopydata('"2020-05-10 20:35:59+0","0.547099113464355","15:35 05/10/2020","0x1c","LOW STATUS","0x85","Normal","73.6","32","29.11","29.31","61.3","24","193","3.8","4.9","22.6","380.54","3082","7","0.00","0.00","0.97","0.97","11.96"
')= ( 1 ) [1 items] at Ambient_Parser.pl line 182
<- pg_putcopyend= ( 1 ) [1 items] at Ambient_Parser.pl line 183
<- commit= ( 1 ) [1 items] at Ambient_Parser.pl line 184
<- DESTROY(DBI::db=HASH(0x3c76ca8))= ( undef ) [1 items] at Ambient_Parser.pl line 193
对于参考线193是最终出口;在文件中。
我必须缺少某些东西,但我看不到它是什么。你能指出我的错误吗?
编辑:我在$ SQL =“ COPY ....和Postgres COPY command documentation中比较了该教程命令中的选项。该教程添加了CSV HEADER选项,这些在Postres文档中没有。我不确定为什么这些选项在教程中使用,或它们导致无提示故障的原因。我删除了它们,现在却遇到错误。
上面的代码现在看起来像这样:
rainofyearly
)
FROM STDIN WITH DELIMITER ','";
这些错误现在正在输出:
DBD::Pg::db pg_putcopyend failed: ERROR: invalid input syntax for type real: ""0.520319223403931""
CONTEXT: COPY ambientweather, line 1, column fetchelapsed: ""0.520319223403931"" at Ambient_Parser.pl line 186.
DBD::Pg::db pg_putcopyend failed: ERROR: invalid input syntax for type real: ""0.520319223403931""
CONTEXT: COPY ambientweather, line 1, column fetchelapsed: ""0.520319223403931"" at Ambient_Parser.pl line 186.
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::Pg::db handle dbname=MyDatabase;host=192.168.1.1;port=5432 at Ambient_Parser.pl line 186.
我正在调查为什么实际价值被视为双引号。这与我在PSQL命令行中使用COPY FROM使用的CSV格式相同,并且如上所示接受了实数。
您告诉它第一行将是忽略的标题。但是您只发送了一行。因此,没有发送数据线。
CSV和HEADER是单独的选项。这些都存在(单独)在您链接到的文档中。您需要保留CSV,否则该报价将无法理解。