2015-08-26 3 views
0

Я написал CGI script in perl. Я получаю POST request к этому сценарию из двух разных мест одновременно. Из запроса POST я заполняю пять разных таблиц. Я получаю 500 строк в каждом POST-запросе, а затем заполняю каждую таблицу 100 строками.Заполнение отсутствующих строк в postgresql

Моя проблема заключается в том, что через некоторое время одна или две таблицы начинают показывать меньшее количество строк. Обе эти таблицы хранят ip в одном из столбцов. Каждый раз только эти две таблицы являются теми, у которых отсутствуют данные, которые для меня странные. Я не могу понять, почему это происходит.

Хотя я получаю что-то в журналах postgresql, а количество таких журналов такое же, как количество строк, отсутствующих в таблице.

UTC STATEMENT: insert into post (ip, count, location, source_server) values ($1, $2, $3, $4) 
UTC STATEMENT: insert into post (ip, count, location, source_server) values ($1, $2, $3, $4) 
UTC STATEMENT: insert into post (ip, count, location, source_server) values ($1, $2, $3, $4) 

Это мой код CGI.

use strict; 
use warnings; 
use CGI; 
use DBI; 
use JSON; 


#Taking parameters passed as post request 
my $conn = CGI->new; 
my $data = $conn->param('POSTDATA'); 

#Details regarding database 
my $host  = 'host'; 
my $user  = 'user'; 
my $password = 'password'; 
my $database = 'db'; 

my ($location, $table, $entry); 

#Creating connection to DB 
my $dsn = "dbi:Pg:dbname=$database;host=$host"; 
my $dbh 
    = DBI->connect($dsn, $user, $password, 
    { RaiseError => 0, PrintError => 0 }) 
    or die("Connection to DB failed $!\n"); 

#Decoding json received in post request to perl hash 
$data = decode_json $data; 

my ($source_server) = keys %$data; 

my $location = 'XX'; 

my $main_data = $$data{$source_server}; 

my @db  = qw /a b c d e/; 
my %mapping = (
    'a' => 'A', 
    'b'  => 'B', 
    'c' => 'C', 
    'd' => 'D', 
    'e' => 'E' 
); 


foreach (@$main_data) { 

    my $hash = $_; 

    #Deciding which table data will be pushed into 
    $table = shift @db; 
    $entry = $mapping{$table}; 

    my $sth = $dbh->prepare(
     "insert into $table ($entry, count, location, source_server) values (?, ?, ?, ?)"); 

    while ((my $key, my $value) = each %$hash) { 
     $sth->execute($key, $value, $location, $source_server); 

    } 
    $sth->finish; 

} 

#Sending 200 status code back to client 
print "Status: 200\n\n"; 

Данные передаются в мой CGI скрипт в формате JSON, как {KEY : [{HASH},{HASH},{HASH},{HASH},{HASH}]}. Второй и пятый хэш содержат данные для таблиц, которые отсутствуют через некоторое время.

Каждый хеш будет иметь 100 пар ключей: значение, таким образом делая общее количество 500 записей.

+0

Откуда вы знаете порядок данных? Звуки типа 'keys% $ data' и' shift @ db' звучат неправильно. Пробальби это только для примера. – simbabque

+0

Добавили ли вы журнал или просмотрели журнал веб-сервера? Также добавьте 'или умереть $ dbh-> errstr' для подготовки и выполнения или включите' PrintError' и 'RaiseError'. Возможно, исходные данные неверны. Вы также можете добавить транзакцию вокруг 'while' или даже' foreach'. – simbabque

+0

@simbabque Поскольку в JSON есть только один ключ, я могу взять этот ключ, используя 'keys% $ data'. Также я получаю массив хэшей и порядок, в котором размещены массивы, и я знаю точно. Поскольку я должен вводить 5 таблиц, которые меняются только на один столбец, поэтому для получения таблицы и одного изменяющегося столбца я создал сопоставление @db и%. – shivams

ответ

0

Ну после комментария simbabque выше i включен RaiseError и PrintError. После этого я могу получить ошибку в журналах ошибок сервера. Журналы ошибок показывают, что из-за одновременной вставки строк из нескольких мест я получаю нарушение первичного ключа, которое вызывало это странное поведение.

Я изменил свой первичный ключ, и все хорошо :)