Potrzebuje skryptu który zapisuje dane z pliku (np.csv) do bazy danych. Proszę o pomoc
Powiedzmy, że masz plik csv - czy wartości mogą być ciągami z przecinkiem?1,2,3,"Hello, world!",4,5
Jeżeli masz pewność, że nigdy takich wartości nie będzie, to możesz lecieć linia po linii i robić zwykły split
na przecinku.
Lepiej jednak po prostu użyć https://metacpan.org/pod/Text::CSV
Odnośnie bazy danych - DBI, bo zakładam, że ORM-a nie potrzebujesz. Ewentualnie coś co działa na DBI: http://search.cpan.org/~juerd/DBIx-Simple-1.35/lib/DBIx/Simple.pm
Powiedzmy że mam taki plik z ulicami
Marszałkowska 128
Ostrobramska 100
Wołoska 98
Potocka 11
KEN 95
I jest ten plik zapisany w csv.
Jakby ktoś mógł napisać taki skrypt który właśnie zapisze te dane (ulice) do bazy postgres.
Jeśli cała linia jest wartością, to nie potrzebujesz parsować tego jako csv (zresztą, i tak nie masz "comma separated values" :P)
use strict;
use DBIx::Simple;
my $db = DBIx::Simple->connect(
'DBI:mysql:database=perltest', # zamiast 'mysql' możesz użyć 'Pg' łącząc się z bazą postgres
'xupicor', '1234', # uzytkownik, hasło
{ RaiseError => 1 } # opcje dodatkowe, RaiseError sprawia, że metody rzucają wyjątkami zamiast zwracać kody błędów
);
$db->query('SET NAMES utf8'); # dla postgresa albo --client_encoding w DSN, albo obejmij utf8 apostrofami, albo SET CLIENT_ENCODING TO
# wczytujemy dane z pliku do bazy
while (<>) { # linia po linii
chomp ; # \n na końcu linii wyrzucamy
$db->query('INSERT INTO locations(address) VALUES (?)', $_);
}
# w terminalu:
#$ perl inserter.pl < address_list.csv
Location(adress) - czyli?
Nie ma tam żadnego "Location(adress)" - jest locations(address)
. locations
to nazwa tabeli, address
to nazwa kolumny.
Zdajesz sobie sprawę z tego, że zanim to zadziała musisz mieć utworzoną odpowiednią bazę danych, prawda?
Potrzebny schemat da się wydedukować z kodu. Tabela locations
przechowuje... lokacje, adresy. W tej tabeli masz kolumnę o nazwie address
przechowującą ciąg znaków będący adresem.
https://www.postgresql.org/docs/current/static/tutorial.html
Jeżeli nic nie wiesz na temat baz danych, SQL i Perla, to może nie na głęboką, ale już troszkę w sadzawkę. :P Da się z niej wyjść dość łatwo po prostu ucząc się od podstaw tych rzeczy.
Powiedzmy, że przyznałbym rację, jeżeli nie miałbyś pojęcia o programowaniu w ogóle.
Mam taki program (patrz załącznik). Jak zrobić teraz
W kodzie, żeby w tej pętli while "rozbić" te dane z jednej linii na zmienne. Separatorem jest znak ";".
Bo później w Insert pod ? Wstawię te zmienne
Daniel Kos 30 lat mężczyzna warszawa
Tomasz wikiel 24 lat mężczyzna Kraków
Elżbieta Pawłowska 60 lat kobieta Wrocław
Katarzyna Kowalczyk 30 lat kobieta Gdańsk
Daniel Kos ; 30lat ; mężczyzna ; warszawa ;
Tomasz; wikiel; 24 lat; mężczyzna ; Kraków ;
Elżbieta Pawłowska ; 60lat; kobieta; Wrocław ;
Katarzyna Kowalczyk ; 30 lat ; kobieta; Gdańsk
$ cat csv.pl
use strict;
use DBIx::Simple;
use Text::CSV;
my $db = DBIx::Simple->connect(
'DBI:mysql:database=perltest',
'xupicor', '1234',
{ RaiseError => 1 }
);
$db->query('SET NAMES utf8');
my $csv = Text::CSV->new ( { sep_char => ';', binary => 1, } )
or die "Cannot use CSV: ".Text::CSV->error_diag ();
open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!";
while (my $row = $csv->getline($fh)) {
my $age = $row->[1];
$age =~ s/(\d+)/$1/;
$db->query("INSERT INTO persons(name, age, sex, city) VALUES(??)",
$row->[0], $age, $row->[2], $row->[3]);
}
$csv->eof or $csv->error_diag();
close $fh;
$ cat test.csv
Daniel Kos;30 lat;mężczyzna;warszawa
Tomasz wikiel;24 lat;mężczyzna;Kraków
Elżbieta Pawłowska;60 lat;kobieta;Wrocław
Katarzyna Kowalczyk;30 lat;kobieta;Gdańsk
$ ...
mysql> select * from persons;
+----+----------------------+-----+-------------+----------+
| id | name | age | sex | city |
+----+----------------------+-----+-------------+----------+
| 1 | Daniel Kos | 30 | mężczyzna | warszawa |
| 2 | Tomasz wikiel | 24 | mężczyzna | Kraków |
| 3 | Elżbieta Pawłowska | 60 | kobieta | Wrocław |
| 4 | Katarzyna Kowalczyk | 30 | kobieta | Gdańsk |
+----+----------------------+-----+-------------+----------+
4 rows in set (0.00 sec)
https://perlmaven.com/how-to-read-a-csv-file-using-perl
Musisz się przyłożyć, bo nawet taki noob jak ja potrafi sklecić tak podstawowy przykład. :P
open(FILE,"<" ,"file.cvs") or die "Error: open file\n";
my @table;
for(my $number_line=0;<FILE>;$number_line++,@table=()){
push(@table,split(/\;/,$_));
print "Line $number_line\n";
for(my $i=0;$i<$#table+1;$i++){
print "$i: ${table[$i]}\n";
}
}