NAME
DBIO - Native relational mapping for Perl, built on DBI
VERSION
version 0.900000
SYNOPSIS
The classes shown below can also be generated from an existing database with dbiogen, powered by DBIO::Generate.
Schema class
package MyApp::Schema;
use DBIO 'Schema';
__PACKAGE__->load_namespaces();
1;
Vanilla style (import sugar)
package MyApp::Schema::Result::Artist;
use DBIO; # Role is auto-detected from the package name: Core
__PACKAGE__->table('artist');
__PACKAGE__->add_columns(qw/ artistid name /);
__PACKAGE__->set_primary_key('artistid');
__PACKAGE__->has_many(cds => 'MyApp::Schema::Result::CD', 'artistid');
1;
The classic equivalent (still supported):
package MyApp::Schema::Result::Artist;
use base 'DBIO::Core';
...
Candy style (import sugar)
DBIO::Candy removes the __PACKAGE__-> boilerplate:
package MyApp::Schema::Result::Artist;
use DBIO::Candy;
table 'artist';
column artistid => { data_type => 'int', is_auto_increment => 1 };
primary_key 'artistid';
column name => { data_type => 'varchar', size => 100 };
has_many cds => 'MyApp::Schema::Result::CD', 'artistid';
1;
Cake style (DDL-like DSL)
DBIO::Cake provides type functions that read like DDL:
package MyApp::Schema::Result::Artist;
use DBIO::Cake;
table 'artist';
col artistid => integer, auto_inc;
col name => varchar(100);
primary_key 'artistid';
has_many cds => 'MyApp::Schema::Result::CD', 'artistid';
1;
Using your schema
use MyApp::Schema;
my $schema = MyApp::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
my @all_artists = $schema->resultset('Artist')->all;
my $johns_rs = $schema->resultset('Artist')->search(
{ name => { like => 'John%' } }
);
# Joins are automatic from relationship conditions
my @rock_cds = $schema->resultset('CD')->search(
{ 'artist.name' => 'John Doe' }
)->all;
# Prefetch related data in a single query
my $millennium_cds_rs = $schema->resultset('CD')->search(
{ year => 2000 },
{ prefetch => 'artist' }
);
my $cd = $millennium_cds_rs->next;
my $artist_name = $cd->artist->name; # no extra query
# Create, update, delete
my $new_cd = $schema->resultset('CD')->create({ title => 'Spoon' });
$schema->txn_do(sub { $new_cd->update({ title => 'Fork' }) });
$millennium_cds_rs->update({ year => 2002 });
DESCRIPTION
DBIO (DBI Objects) is a relational mapper for Perl built on top of DBI. It combines an object model for rows and result classes with a resultset API for building queries without giving up database-native behavior.
Three styles are available for defining result classes: DBIO::Cake (DDL-like DSL), DBIO::Candy (import sugar), and the classic Vanilla style (use DBIO; or use base 'DBIO::Core').
Database-specific features are provided by native driver distributions (DBIO::PostgreSQL, DBIO::MySQL, DBIO::SQLite, etc.) that speak each database's dialect natively.
Key features:
Automatic joins from relationship conditions
Lazy ResultSets that only query when you ask for rows
Prefetch for efficient eager loading
Multi-column primary and foreign keys
Database-level paging, driver-specific SQL features
Three result class styles: Cake, Candy, Vanilla
DBIO is pre-1.0. The core API is substantial and usable, but some edges are still being refined. Please report anything that looks wrong or surprising.
METHODS
skill
my $markdown = DBIO->skill('postgresql-database');
Class-level shortcut for "skill" in DBIO::Skills: returns the markdown text of the named agent skill from whatever DBIO distributions are currently loaded, or undef. The leading dbio- is optional.
skills
my @names = DBIO->skills;
Class-level shortcut for "skills" in DBIO::Skills: the sorted names of all skills available from the currently loaded DBIO distributions.
USE-AS-PRAGMA
Since DBIO.pm itself is a sugar pragma (analogous to Moose.pm), it can be used directly to declare a DBIO class. The role to inherit from is auto-detected from the package name, or can be specified explicitly.
package MyApp::Schema::Result::Artist;
use DBIO; # -> @ISA = ('DBIO::Core')
package MyApp::Schema::ResultSet::Artist;
use DBIO; # -> @ISA = ('DBIO::ResultSet')
package MyApp::Schema;
use DBIO 'Schema'; # -> @ISA = ('DBIO::Schema')
package MyApp::Schema::Result::Photo;
use DBIO 'Core'; # explicit override
Shortcuts can be combined with role selection, separated by leading dashes. A shortcut loads a driver's ::Result component:
use DBIO -pg; # Core + load the PostgreSQL::Result component
use DBIO 'Schema', -pg; # Schema + load the PostgreSQL::Result component
Shortcuts are owned by the driver distributions, not by core; core never names a single driver. A shortcut resolves in two tiers:
An explicit stub
DBIO::Shortcut::<key>, which a driver ships for each curated alias (-pg,-my, ...). Core lazy-loads it and calls itsapply($caller), which usually just delegates toDBIO->apply_driver:package DBIO::Shortcut::pg; sub apply { DBIO->apply_driver($_[1], 'PostgreSQL') } 1;If there is no stub, core falls back to an already-loaded driver whose name matches the key case-insensitively -- so
-postgresqlresolves toDBIO::PostgreSQLonce that driver is loaded, with no stub needed.
apply_driver($caller, $name) applies the driver by convention: on a Schema it pins storage_type('+DBIO::<name>::Storage'); on a Result class it loads the <name>::Result component if the driver ships one. So every driver gets a shortcut (the Schema path works for all), and a ::Result component is just an extra. A shortcut that resolves to nothing dies with a helpful message -- it only works when its driver is installed (and, for the bare canonical name, loaded).
Role auto-detection rules:
package matches
/::Result::WORD$/→ roleCorepackage matches
/::ResultSet::WORD$/→ roleResultSetanything else → role
Core(the most common case)
use DBIO; additionally enables strict and warnings in the caller, matching the behavior of DBIO::Candy, DBIO::Cake, DBIO::Moo and DBIO::Moose.
WHERE TO START
See DBIO::Manual::DocMap for the full documentation map. New users should start with DBIO::Manual::QuickStart.
HERITAGE
DBIO is a fork of DBIx::Class with a clean namespace break. Key changes:
Namespace:
DBIO::replacesDBIx::Class::SQL::Abstract replaces SQL::Abstract::Classic
LIMIT/OFFSET via
apply_limiton the driver's SQLMaker instead of string-based dialect dispatchSQL::Translator has been removed; schema introspection, diff, and deployment are handled by DB-specific native modules
Shared utilities (DBIO::SQL::Util) provide
_quote_identand_split_statementfor cross-driver useDBIx::Class::TimeStamp and DBIx::Class::Helpers functionality integrated into core
Native driver distributions for each database (DBIO::PostgreSQL, DBIO::MySQL, DBIO::SQLite, DBIO::DuckDB) use desired-state deployment via test-and-compare; extracted drivers (DBIO::DB2, DBIO::Firebird, DBIO::Informix, DBIO::MSSQL, DBIO::Oracle, DBIO::Sybase) follow the same pattern
Meta-infrastructure has been split into DBIO::Base (inherited by all internal classes);
DBIO.pmis now a pure sugar pragma
GETTING HELP
Codeberg Issues: https://codeberg.org/dbio/dbio/issues
IRC:
#dbioonirc.perl.org
CONTRIBUTING
Contributions are welcome: bug reports, documentation improvements, pull requests, or patches.
Repository: https://codeberg.org/dbio/dbio
AUTHORS
DBIO is built on top of DBIx::Class, which was a long-running collaborative effort by many contributors. See the AUTHORS file for the full list.
AUTHOR
DBIO & DBIx::Class Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.