junij 25th, 2008Dobra vila za SQL
Naključje …
Perl module z imenom SQLFairy (SQL::Translator) sem odkril čisto po naključju med tem ko sem se spoznaval z Doctrine. Ta ORM za PHP do verzije 0.11 ne omogoča da bi mu preprečili avtomatsko “singularizacijo” “podatkovnih modelov” ki jih generiramo iz trenutne baze. Da ponazorim: če imamo tabelo z imenom “files”, bo Doctrine generiral model z imenom “File” in ne “Files”. Čeprav mi ni ravno jasno kako[1], določeni modeli dobijo kar čudna imena ;)[2] .
Da ne bi vedno znova popravljal YAML datoteko, ki opisuje shemo podatkovne baze, sem se lotil malega raziskovanja. Naletel sem na …
SQLFairy …
ali z drugim imenom SQL::Translator. To orodje za SQL, je trenutno najbolj enostavni način za manipulacijo z “podatkovnimi strukturami”[3] na vse mogoče načine. Služi nam lahko za konvertiranje med različnimi “dialekti” CREATE sintaks (npr: iz MySQL v PostgreSQL), za virtualizacijo shem (pseudo-ER diagrami z uporabo: GraphViz ali GD-ja), za konvertiranje ne-RDMBS datotek v SQL sheme (Excelove preglednice), ter še kaj bi se našlo.
Z razbitjem kode v “parserje”[4] in “izdelovalce”[5], je zmožen kombinacije kateregakoli parserja z izbranim izdelovalcem. Trenutno pa je SQLFairy sposoben uporabljati le definicijski del SQL-a[6], ne pa same manipulacije s podatki[7].
Namestitev in konfiguracija
Za začetek si prenesite SQL::Translator na disk. Ker gre za standardne Perl module, je inštalacija sila preprosta, sledite le navodilam v README fajlu.[8]
Po razpakiranju paketa sledimo navodilom:
$ perl Build.PL $ ./Build $ ./Build test $ su # ./Build install
V primeru da nimate inštaliranih vseh ustreznih modulov, ki jih rabi SQL::Translator se bo skripta Build.PL ustavila. Če do sedaj niste kaj prida uporabljali Perl bo vam najverjetneje manjkal modul z imenom’Module::Build‘, ki je potreben za grajenje in inštalacijo Perl modulov. Najenostavnejši način, da si inštaliramo manjkajoče zadeve, je z uporabo CPAN-a. Ukaze lahko vnašamo direktno v konzolo ali pa preko -MCPAN vmesnika.[9]
Primer vnosa direktno v konzolo:
# sudo perl -MCPAN -e 'install Module::Build'
Sledila bo konfiguracija CPAN modula, ter inštalacija Module::Build. Konfiguracija se ustavi, če nimate vseh ustreznih programčkov, ki jih CPAN rabi. Meni sta manjkala: NcFtp klient ter GnuPG. Po cca. 15 minutah v pričakovanju vtipkamo nesrečni “./Build install” :)
Sqlt
Če ste se uspešno prebili do te točke bi sedaj morali imeti na voljo ukaz “sqlt”. Ukaz konvertira SQL sheme z uporabo SQL::Translator-ja. Tipičen primer uporabe je:
sqlt -f MySQL -t PostgreSQL dump_mysql.sql > dump_postgresql.sql
Končni rezultat je opis tabel v datoteki dump_postgresql.sql v sintaksi PostgreSQL-a, ki smo ga konvertirali iz MySQL sintakse.
Spisek vseh možnih parserjev in izdelovalcev dobimo:
sqlt -l

Spisek vseh možnih parserjev in izdelovalcev.
Use cases
Kot primer bomo vzeli SQL DDL psevdokodo, ki jo bomo iz MySQL sintakse konvertirali v različne formate.
Psevdokoda:
CREATE TABLE bugs ( bug_id INTEGER NOT NULL PRIMARY KEY, bug_description VARCHAR(100), bug_status VARCHAR(20), reported_by VARCHAR(100), assigned_to VARCHAR(100), verified_by VARCHAR(100) );
MySQL sintaksa:
CREATE TABLE `bugs` ( `bug_id` int(11) NOT NULL, `bug_description` varchar(100) default NULL, `bug_status` varchar(20) default NULL, `reported_by` varchar(100) default NULL, `assigned_to` varchar(100) default NULL, `verified_by` varchar(100) default NULL, PRIMARY KEY (`bug_id`) ) ENGINE=MyISAM;
Konverzija v PostgreSQL:
sqlt -f MySQL -t PostgreSQL bugs_mysql.sql > bugs_postgresql.sql
PostgreSQL sintaksa:
CREATE TABLE "bugs" (
"bug_id" bigint NOT NULL,
"bug_description" character varying(100) DEFAULT NULL,
"bug_status" character varying(20) DEFAULT NULL,
"reported_by" character varying(100) DEFAULT NULL,
"assigned_to" character varying(100) DEFAULT NULL,
"verified_by" character varying(100) DEFAULT NULL,
PRIMARY KEY ("bug_id")
);
Konverzija v YAML:
sqlt -f MySQL -t YAML bugs_mysql.sql > bugs.yaml
YAML sintaksa:
schema:
procedures: {}
tables:
bugs:
constraints:
- deferrable: 1
expression: ''
fields:
- bug_id
match_type: ''
name: ''
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: PRIMARY KEY
fields:
assigned_to:
data_type: varchar
default_value: NULL
extra: {}
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: assigned_to
order: 5
size:
- 100
bug_description:
data_type: varchar
default_value: NULL
extra: {}
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: bug_description
order: 2
size:
- 100
bug_id:
data_type: int
default_value: ~
extra: {}
is_nullable: 0
is_primary_key: 1
is_unique: 0
name: bug_id
order: 1
size:
- 11
bug_status:
data_type: varchar
default_value: NULL
extra: {}
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: bug_status
order: 3
size:
- 20
reported_by:
data_type: varchar
default_value: NULL
extra: {}
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: reported_by
order: 4
size:
- 100
verified_by:
data_type: varchar
default_value: NULL
extra: {}
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: verified_by
order: 6
size:
- 100
indices: []
name: bugs
options:
- ENGINE: MyISAM
order: 1
triggers: {}
views: {}
translator:
add_drop_table: 0
filename: bugs_mysql.sql
no_comments: 0
parser_args:
db_password: ~
db_user: ~
dsn: ~
field_separator: ~
mysql_parser_version: ~
record_separator: ~
scan_fields: 1
trim_fields: 1
parser_type: SQL::Translator::Parser::MySQL
producer_args:
add_prefix: ~
add_truncate: ~
db_password: ~
db_user: ~
dsn: ~
imap_file: ~
imap_url: ~
indent: ~
newlines: ~
package_name: ~
prefix: ~
pretty: ~
skip: ~
skiplike: ~
title: ~
tt_conf: {}
tt_vars: {}
ttfile: ~
producer_type: SQL::Translator::Producer::YAML
show_warnings: 0
trace: 0
version: 0.09000
Konverzija v XML:
sqlt -f MySQL -t XML bugs_mysql.sql > bugs.xml
XML sintaksa:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Created by SQL::Translator::Producer::XML::SQLFairy
Created on Wed Jun 25 13:40:31 2008
-->
<schema name="" database="" xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
<extra />
<tables>
<table name="bugs" order="1">
<extra />
<fields>
<field name="bug_id" data_type="int" size="11" is_nullable="0" is_auto_increment="0" is_primary_key="1" is_foreign_key="0" order="1">
<extra />
<comments></comments>
</field>
<field name="bug_description" data_type="varchar" size="100" is_nullable="1" default_value="NULL" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="2">
<extra />
<comments></comments>
</field>
<field name="bug_status" data_type="varchar" size="20" is_nullable="1" default_value="NULL" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="3">
<extra />
<comments></comments>
</field>
<field name="reported_by" data_type="varchar" size="100" is_nullable="1" default_value="NULL" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="4">
<extra />
<comments></comments>
</field>
<field name="assigned_to" data_type="varchar" size="100" is_nullable="1" default_value="NULL" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="5">
<extra />
<comments></comments>
</field>
<field name="verified_by" data_type="varchar" size="100" is_nullable="1" default_value="NULL" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="6">
<extra />
<comments></comments>
</field>
</fields>
<indices></indices>
<constraints>
<constraint name="" type="PRIMARY KEY" fields="bug_id" reference_table="" reference_fields="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1">
<extra />
</constraint>
</constraints>
<comments></comments>
</table>
</tables>
<views></views>
<triggers></triggers>
<procedures></procedures>
</schema>
Happy blogging(coding)!
- Nisem se poglabljal v kodo ki generira imena modelov [↩]
- moneta je postala “Monetum” [↩]
- structured data definitions – schemes [↩]
- parsers [↩]
- producers [↩]
- CREATE, ALTER [↩]
- INSERT, UPDATE, DELETE [↩]
- Tukaj predvidevamo da imate Perl ustrezno inštaliran na vašem računalniku [↩]
- kot super-user [↩]