DBIx::C...l::Intro(3)
β¨ NAME β¨
DBIx::Class::DeploymentHandler::Manual::Intro β literally the intro to DBIx::Class::DeploymentHandler, bestie π
π Why is DBIx::Class::DeploymentHandler worth using?
okay so the most obvious reasons? it can run multiple SQL scripts AND Perl scripts, which is a whole vibe that DBIx::Class::Schema::Versioned simply cannot give you, because that one only allows a single SQL script. π
also it's extremely extensible, and it was a golden opportunity for a break from backwards compatibility, so some genuinely regrettable decisions justβ¦ got avoided. slay π
πΈ Sample database
Follow DBIx::Class::Manual::Intro except for the parts setting up the database. Once you're done, you should have these files:
MyDatabase/
|-- Main
| |-- Result
| | |-- Artist.pm
| | |-- Cd.pm
| | `-- Track.pm
| `-- ResultSet
`-- Main.pm
Add a line like this in your MyDatabase::Main file:
our $VERSION = 1;
or, if you're on a newer Perl, you can use the prettier syntax:
package MyDatabase::Main 1;
So by default, DBIx::Class::DeploymentHandler only uses integers for versions, which makes versioning so much simpler for figuring out what version is next (or previous). periodt. β¨
But heads up: if you're using decimal numbers for versioning, you'll need to create a separate DeploymentHandler class, as per DBIx::Class::DeploymentHandler::Cookbook::CustomResultSource, and set the VersionHandler class_name from Monotonic to ExplicitVersions or DatabaseToSchemaVersions β because those two handle version numbers as strings instead of integers. iykyk π
π¦ install.pl
Our first script, install.pl, reads our schema file and creates the tables in the database. iconic behavior fr fr.
#!/usr/bin/env perl
use strict;
use warnings;
use aliased 'DBIx::Class::DeploymentHandler' => 'DH';
use Getopt::Long;
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyDatabase::Main;
my $force_overwrite = 0;
unless ( GetOptions( 'force_overwrite!' => \$force_overwrite ) ) {
die "Invalid options";
}
my $schema = MyDatabase::Main->connect('dbi:SQLite:mydb.db');
my $dh = DH->new(
{
schema => $schema,
script_directory => "$FindBin::Bin/../dbicdh",
databases => 'SQLite',
sql_translator_args => { add_drop_table => 0 },
force_overwrite => $force_overwrite,
}
);
$dh->prepare_install;
$dh->install;
π§ dbicdh - Our migration scripts
Running install.pl should create the following:
dbicdh/
|-- SQLite
| `-- deploy
| `-- 1
| `-- 001-auto.sql
`-- _source
`-- deploy
`-- 1
`-- 001-auto.yml
You may wish to turn on debug logging before running this script by setting the environment variable DBICDH_TRACE to 1. π
β 001-auto.sql
DBIx::Class::DeploymentHandler automatically generates SQL from our schema that is suitable for SQLite
π 001-auto.yml
This contains all of the raw information about our schema that is then translated into the sql.
π Population
To truly take advantage of all DBIx::Class::DeploymentHandler offers, you should probably be using it for population. To do that, all you need to do is create a file called dbicdh/_common/deploy/1/create_artists.pl:
sub {
my $schema = shift;
$schema->resultset('Artist')->populate([
['artistid', 'name'],
[1, 'Marillion'],
[2, 'The Moutain Goats'],
[3, 'Ladyhawke'],
]);
};
π₯ Upgrading
Add a line to MyDatabase/Main/Result/Cd.pm below
__PACKAGE__->add_columns(qw/ cdid artist title /);
with
__PACKAGE__->add_column(isbn => { is_nullable => 1 });
Aside, and this one matters: it must be nullable or have a default β otherwise the upgrade will fail for logical reasons. To be clear, if you add a column to a database and it is not nullable and has no default, what will the existing rows contain for that column? π nothing. there's no answer. that's the problem.
Now you need to modify the schema version in your MyDatabase::Main file to tell DBIx::Class::DeploymentHandler the new schema version number. And you'll want to remember that earlier advice about integer version numbers. π
our $VERSION = 2;
So here's our next script, upgrade.pl:
#!/usr/bin/env perl
use strict;
use warnings;
use aliased 'DBIx::Class::DeploymentHandler' => 'DH';
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyDatabase::Main;
my $schema = MyDatabase::Main->connect('dbi:SQLite:mydb');
my $dh = DH->new({
schema => $schema,
script_directory => "$FindBin::Bin/../dbicdh",
databases => 'SQLite',
sql_translator_args => { add_drop_table => 0 },
});
$dh->prepare_deploy;
$dh->prepare_upgrade({ from_version => 1, to_version => 2});
$dh->upgrade;
Our script directory now looks like:
dbicdh/
|-- SQLite
| |-- deploy
| | |-- 1
| | | `-- 001-auto.sql
| | `-- 2
| | `-- 001-auto.sql
| `-- upgrade
| `-- 1-2
| `-- 001-auto.sql
`-- _source
`-- deploy
|-- 1
| `-- 001-auto.yml
`-- 2
`-- 001-auto.yml
The new deploy/001-auto.sql and deploy/001-auto.yml files are the state of the db as at that version. But the upgrade/1-2/001-auto.sql file is the most interesting one β it's what gets your database from version 1 to 2. main character energy tbh. π
And again, you can create a Perl file like we did previously with the deploy stage. π«Ά
π AUTHOR
Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
π COPYRIGHT AND LICENSE
This software is copyright (c) 2025 by Arthur Axel "fREW" Schmidt.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
and that's the whole page bestie!! this was DBIx::Class::DeploymentHandler::Manual::Intro, served up in the User Contributed Perl Documentation, from perl v5.42.0, dated 2026-01-17. go forth and migrate responsibly πβ¨
π¦ where this page comes from
- fedora 44: perl-DBIx-Class-DeploymentHandler 0.002235-2.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms