为什么Perl DBI接口无法插入到Postgres表中?

问题描述 投票:2回答:1

我开发了一个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格式相同,并且如上所示接受了实数。

postgresql perl dbi
1个回答
0
投票

您告诉它第一行将是忽略的标题。但是您只发送了一行。因此,没有发送数据线。

CSV和HEADER是单独的选项。这些都存在(单独)在您链接到的文档中。您需要保留CSV,否则该报价将无法理解。

© www.soinside.com 2019 - 2024. All rights reserved.