SQL::Tr...::Manual(3)
NAME
SQL::Translator::Manual β the sqlfairy user manual π (yes, this is the SQL::Translator::Manual(3) page from User Contributed Perl Documentation, bestie)
SYNOPSIS β¨
SQL::Translator (AKA "SQLFairy") is a collection of modules for transforming (mainly) SQL DDL files into a variety of other formats, including other SQL dialects, documentation, images, and code. In this manual, we will attempt to address how to use SQLFairy for common tasks. For a lower-level discussion of how the code works, please read the documentation for SQL::Translator.
It may prove helpful to have a general understanding of the SQLFairy code before continuing. The code can be broken into three conceptual groupings:
- Parsers β responsible for reading the input files and describing them to the Schema object middleware. π₯
- Producers β create the output as described by the Schema middleware. π€
- Schema objects β bridge the communication between the Parsers and Producers by representing any parsed file through a standard set of generic objects to represent concepts like Tables, Fields (columns), Indices, Constraints, etc. π§©
It's not necessary to understand how to write or manipulate any of these for most common tasks, but you should be aware of the concepts as they will be referenced later in this document.
SQLFAIRY SCRIPTS π§
Most common tasks can be accomplished through the use of the script interfaces to the SQL::Translator code. All SQLFairy scripts begin with sqlt.. Here are the scripts and a description of what they each do:
sqltβ the main interface for text-to-text translations, e.g., converting a MySQL schema to Oracle. πsqlt-diagramβ a tailored interface for the Diagram producer and its many myriad options. π¨sqlt-diffβ examines two schemas and reports the SQL commands (ALTER,CREATE) needed to turn the first schema into the second. π΅οΈsqlt-dumperβ generates a Perl script that can be used to connect to a database and dump the data in each table in different formats, similar to themysqldumpprogram. π¦sqlt-graphβ an interface to the GraphViz visualization tool and its myriad options. πsqlt.cgiβ a CGI script that presents an HTML form for uploading or pasting a schema and choosing an output and the output options. π
To read the full documentation for each script, use perldoc (or execute any of the command-line scripts with the --help flag). π
CONVERTING SQL DIALECTS π
Probably the most common task SQLFairy is used for is to convert one dialect of SQL to another. If you have a text description of an SQL database (AKA a "DDL" β "Data Definition Language"), then you should use the sqlt script with switches to indicate the parser and producer and the name of the text file as the final argument. For example, to convert the foo.sql MySQL schema to a version suitable for PostgreSQL, you would do the following:
$ sqlt -f MySQL -t PostgreSQL foo.sql > foo-pg.sql
The from and to options are case-sensitive and must match exactly the names of the Parser and Producer classes in SQL::Translator. For a complete listing of your options, execute sqlt with the --list flag. π
EXTRACT SQL SCHEMAS DIRECTLY FROM DATABASE ποΈ
It is possible to extract some schemas directly from the database without parsing a text file (the foo.sql in the above example). This can prove significantly faster than parsing a text file. To do this, use the DBI parser and provide the necessary arguments to connect to the database and indicate the producer class, like so:
$ sqlt -f DBI --dsn dbi:mysql:FOO --db-user guest \
--db-password p4ssw0rd -t PostgreSQL > foo
The --list option to sqlt will show the databases supported by DBI parsers. ποΈ
HANDLING NON-SQL DATA π
Certain structured document formats can be easily thought of as tables. SQLFairy can parse Microsoft Excel spreadsheets and arbitrarily delimited text files just as if they were schemas which contained only one table definition. The column names are normalized to something sane for most databases (whitespace is converted to underscores and non-word characters are removed), and the data in each field is scanned to determine the appropriate data type (character, integer, or float) and size. For instance, to convert a comma-separated file to an SQLite database, do the following:
$ sqlt -f xSV --fs ',' -t SQLite foo.csv > foo-sqlite.sql
Additionally, there is a non-SQL representation of relational schemas namely XML. Additionally, the only XML supported is our own version; however, it would be fairly easy to add an XML parser for something like the TorqueDB (http://db.apache.org/torque/) project. The actual parsing of XML should be trivial given the number of XML parsers available, so all that would be left would be to map the specific concepts in the source file to the Schema objects in SQLFairy. π§
To convert a schema in SQLFairy's XML dialect to Oracle, do the following:
$ sqlt -f XML-SQLFairy -t Oracle foo.xml > foo-oracle.sql
SERIALIZING SCHEMAS π
Parsing a schema is generally the most computationally expensive operation performed by SQLFairy, so it may behoove you to serialize a parsed schema if you need to perform repeated conversions. For example, as part of a build process the author converts a MySQL schema first to YAML, then to PostgreSQL, Oracle, SQLite and Sybase. Additionally, a variety of documentation in HTML and images is produced. This can be accomplished like so:
$ sqlt -f MySQL -t YAML schema-mysql.sql > schema.yaml
$ sqlt -f YAML -t Oracle schema.yaml > schema-oracle.sql
$ sqlt -f YAML -t PostgreSQL schema.yaml > schema-postgresql.sql
$ ...
SQLFairy has three serialization producers, none of which is superior to the other in their description of a schema. π
XML-SQLFairyβ the aforementioned XML format. It is essentially a direct mapping of the Schema objects into XML. This can also provide a very convenient bridge to describing a schema to a non-Perl application. Providing a producer argument tosqltof justXMLwill default to usingXML-SQLFairy. πStorableβ stores the Schema object using Perl'sStorable.pmmodule available on CPAN. ποΈYAMLβ serialized the Schema object with the very readable structured data format of YAML (http://www.yaml.org/). Earlier examples show serializing to YAML. π
VISUALIZING SQL SCHEMAS π¦
The visualization tools in SQLFairy can graphically represent the tables, fields, datatypes and sizes, constraints, and foreign key relationships in a very compact and intuitive format. This can be very beneficial in understanding and document large or small schemas. Two producers in SQLFairy will create pseudo-E/R (entity-relationship) diagrams:
Diagramβ the first visualization tool in SQLFairy, this producer useslibgdto draw a picture of the schema. The tables are evenly distributed in definition order running in columns (i.e., no graphing algorithms are used), so many of the lines showing the foreign key relationships may cross over each other and the table boxes. Please read the documentation of thesqlt-diagramscript for all the options available to this producer. π§GraphVizβ the layout of the GraphViz producer is far superior to the Diagram producer as it uses the Graphviz binary from Bell Labs to create very professional-looking graphs. There are several different layout algorithms and node shapes available. Please see the documentation of thesqlt-graphscript for more information. π
AUTOMATED CODE-GENERATION π€
Given that so many applications interact with SQL databases, it's no wonder that people have automated code to deal with this interaction. Class::DBI from CPAN is one such module that allows a developer to describe the relationships between tables and fields in class declarations and then generates all the SQL to interact (SELECT, UPDATE, DELETE, INSERT statements) at runtime. Obviously, the schema already describes itself, so it only makes sense that you should be able to generate this kind of code directly from the schema. The ClassDBI producer in SQLFairy does just this, creating a Perl module that inherits from Class::DBI and sets up most of the code needed to interact with the database. Here is an example of how to do this:
$ sqlt -f MySQL -t ClassDBI foo.sql > Foo.pm
Then simply edit Foo.pm as needed and include it in your code. π«Ά
CREATING A DATA DUMPER SCRIPT πΎ
The Dumper producer creates a Perl script that can select the fields in each table and then create INSERT statements for each record in the database similar to the output generated by MySQL's mysqldump program:
$ sqlt -f YAML -t Dumper --dumper-db-user guest \
> --dumper-db-pass p4ssw0rd --dumper-dsn dbi:mysql:FOO \
> foo.yaml > foo-dumper.pl
And then execute the resulting script to dump the data:
$ chmod +x foo-dumper.pl
$ ./foo-dumper.pl > foo-data.sql
The dumper script also has a number of options available. Execute the script with the --help flag to read about them. π§
DOCUMENTING WITH SQL::TRANSLATOR π
SQLFairy offers two producers to help document schemas:
HTMLβ creates a single HTML document which uses HTML formatting to describe the Schema objects and to create hyperlinks on foreign key relationships. This can be a surprisingly useful documentation aid as it creates a very readable format that allows one to jump easily to specific tables and fields. It's also possible to plugin your own CSS to further control the presentation of the HTML. π¨PODβ arguably not that useful of a producer by itself, but the number of POD-conversion tools could be used to further transform the POD into something more interesting. The schema is basically represented in POD sections where tables are broken down into fields, indices, constraints, foreign keys, etc. π
β¨ TEMPLATE-BASED MANIPULATION OF SCHEMA OBJECTS β¨
okay bestie, picture this: every producer that creates text output could've been built with a templating system that mixes dynamic output into static text. CPAN has several diverse templating systems, but few are as powerful as Template Toolkit (http://www.template-toolkit.org/). You can easily create your own producer without writing any Perl code at all β just write a template using Template Toolkit's syntax. That template gets a reference to the Schema object (the one briefly described at the beginning of this document and mentioned many times throughout). For example, here's a template that simply prints the name of each table and field:
# file: schema.tt
[% FOREACH table IN schema.get_tables %]
Table: [% table.name %]
Fields:
[% FOREACH field IN table.get_fields -%]
[% field.name %]
[% END -%]
[% END %]
Then process it like so:
$ sqlt -f YAML -t TTSchema --template schema.tt foo.yaml
and get output like this:
Table: foo
Fields:
foo_id
foo_name
For more information on Template Toolkit, please install the Template module and read the POD. π
π FINDING THE DIFFERENCES BETWEEN TWO SCHEMAS π
so like, sqlt-diff examines two schemas and creates SQL schema modification statements that can transform the first schema into the second. The flag syntax is a little quirky:
$ sqlt-diff foo-v1.sql=MySQL foo-v2.sql=Oracle > diff.sql
As you can see, the schemas don't even need to be from the same vendor. But heads up: that can produce some spurious results, because datatypes aren't currently viewed as equivalent unless they match exactly β even if they'd be converted to the same thing. For example, MySQL's integer data type would be converted to Oracle's number, but the differ isn't quite smart enough yet to figure this out. Also, since the SQL to ALTER a field definition varies from database vendor to vendor, these statements are made using just the keyword CHANGE, and they'll likely need to be corrected for the target database. π
π₯οΈ A UNIFIED GRAPHICAL INTERFACE π₯οΈ
After seeing all those options and scripts, maybe you're pining for a single, graphical interface to handle all these transformations and choices? That's exactly what the sqlt.cgi script gives you. Just drop that script into your web server's CGI directory, enable the execute bit, and point your web browser at an HTML form that gives you a simple interface to all the SQLFairy parsers and producers. π
π§ PLUGIN YOUR OWN PARSERS AND PRODUCERS π§
Now that you've seen how the parsers and producers interact via the Schema objects, maybe you want to create your own versions to plugin.
Producers are probably the easier concept to grok, so let's cover that first. By far the easiest way to create custom output is to use the TTSchema producer with a Template Toolkit template, like we described earlier. But you can also easily pass a reference to a subroutine that SQL::Translator can call to produce the output. That subroutine gets a single argument: the SQL::Translator object, which you can use to access the Schema objects. Please read the POD for SQL::Translator and SQL::Translator::Schema to learn the methods you can call. Here's a very simple example:
#!/usr/bin/perl
use strict;
use SQL::Translator;
my $input = q[
create table foo (
foo_id int not null default '0' primary key,
foo_name varchar(30) not null default ''
);
create table bar (
bar_id int not null default '0' primary key,
bar_value varchar(100) not null default ''
);
];
my $t = SQL::Translator->new;
$t->parser('MySQL') or die $t->error;
$t->producer( \&produce ) or die $t->error;
my $output = $t->translate( \$input ) or die $t->error;
print $output;
sub produce {
my $tr = shift;
my $schema = $tr->schema;
my $output = '';
for my $t ( $schema->get_tables ) {
$output .= join('', "Table = ", $t->name, "\n");
}
return $output;
}
Executing this script produces the following:
$ ./my-producer.pl
Table = foo
Table = bar
A custom parser gets passed two arguments: the SQL::Translator object and the data to be parsed. In this example, the schema is represented in a simple text format. Each line is a table definition where the fields are separated by colons. The first field is the table name, and the following fields are column definitions where the column name, data type and size are separated by spaces. The specifics of the example aren't important β what's being demonstrated is that you have to decide how to parse the incoming data and then map the concepts in the data to the Schema object.
#!/usr/bin/perl
use strict;
use SQL::Translator;
my $input =
"foo:foo_id int 11:foo_name varchar 30\n" .
"bar:bar_id int 11:bar_value varchar 30"
;
my $t = SQL::Translator->new;
$t->parser( \&parser ) or die $t->error;
$t->producer('Oracle') or die $t->error;
my $output = $t->translate( \$input ) or die $t->error;
print $output;
sub parser {
my ( $tr, $data ) = @_;
my $schema = $tr->schema;
for my $line ( split( /\n/, $data ) ) {
my ( $table_name, @fields ) = split( /:/, $line );
my $table = $schema->add_table( name => $table_name )
or die $schema->error;
for ( @fields ) {
my ( $f_name, $type, $size ) = split;
$table->add_field(
name => $f_name,
data_type => $type,
size => $size,
) or die $table->error;
}
}
return 1;
}
And here is the output produced by this script:
--
-- Created by SQL::Translator::Producer::Oracle
-- Created on Wed Mar 31 15:43:30 2004
--
--
-- Table: foo
--
CREATE TABLE foo (
foo_id number(11),
foo_name varchar2(30)
);
--
-- Table: bar
--
CREATE TABLE bar (
bar_id number(11),
bar_value varchar2(30)
);
If you create a useful parser or producer, you are encouraged to submit your work to the SQLFairy project! π«Ά
π PLUGIN TEMPLATE TOOLKIT PRODUCERS π
Maybe you find that the TTSchema producer doesn't give you enough control over templating and you want to play with the Template config or add your own variables. Or maybe you just have a really good template you want to submit to SQLFairy :) If so, the SQL::Translator::Producer::TT::Base producer may be just for you! Instead of working like a normal producer, it provides a base class so you can cheaply build new producer modules based on templates.
Its simplest use is when you just want to put a single template in its own module. So to create a Foo producer, create a Custom/Foo.pm file like this, putting your template in the __DATA__ section:
package Custom::Foo.pm;
use base qw/SQL::Translator::Producer::TT::Base/;
# Use our new class as the producer
sub produce { return __PACKAGE__->new( translator => shift )->run; };
__DATA__
[% FOREACH table IN schema.get_tables %]
Table: [% table.name %]
Fields:
[% FOREACH field IN table.get_fields -%]
[% field.name %]
[% END -%]
[% END %]
For that we get a producer called Custom::Foo that we can now call like a normal producer (as long as the directory with Custom/Foo.pm is in our @INC path):
$ sqlt -f YAML -t Custom-Foo foo.yaml
The template gets variables of schema and translator to use in building its output. You also get a number of methods you can override to hook into the template generation. β¨
tt_config lets you set the config options used by the Template object. The Template Toolkit provides a huge number of options which allow you to do all sorts of magic (see Template::Manual::Config for details). This method provides a hook into them by returning a hash of options for the Template. e.g. say you want to use the INTERPOLATE option to save some typing in your template:
sub tt_config { ( INTERPOLATE => 1 ); }
Another common use for this is to add your own filters to the template:
sub tt_config {(
INTERPOLATE => 1,
FILTERS => { foo_filter => \&foo_filter, }
);}
Another common extension is adding your own template variables. This is done with tt_vars:
sub tt_vars { ( foo => "bar" ); }
What about using template files instead of DATA sections? You can already β if you give a template on the command line, your new producer will use that instead of reading the DATA section:
$ sqlt -f YAML -t Custom-Foo --template foo.tt foo.yaml
This is useful as you can set up a producer that adds a set of filters and variables that you can then use in templates given on the command line. (There is also a tt_schema method to override if you need even finer control over the source of your template.) Note that if you leave out the DATA section all together, then your producer will require a template file name to be given.
See SQL::Translator::Producer::TT::Base for more details. π
πΈ AUTHOR πΈ
Ken Y. Clark <kclark@cpan.org>. π
That's the whole page, bestie! This one came from perl v5.42.0, dated 2024-12-12, and it's SQL::Tr...::Manual(3). Stay slay and keep your schemas cute. π
β¨π
π¦ where this page comes from
- opensuse-leap 16.0: perl-SQL-Translator 1.660.0-bp160.1.11 Β· (Artistic-1.0 OR GPL-1.0-or-later) AND GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms