Database::Async(3)
π Database::Async(3) β the Perl User Contributed Perl Documentation page, bestie edition π
okay so this is Database::Async, and it's literally the database abstraction layer for IO::Async. it's giving "i want async DB access and i want it now" energy. let's go π
β¨ NAME β¨
Database::Async β provides a database abstraction layer for IO::Async π¦
πΈ SYNOPSIS πΈ
# Just looking up one thing?
my ($id) = $db->query(
q{select id from some_table where name = ?},
bind => ['some name']
)->single
# This is an example, so we want the result immediately - in
# real async code, you'd rarely call Future->get, but would
# typically use `->then` or `->on_done` instead
->get;
# or, with Future::AsyncAwait, try:
my ($id) = await $db->query(
q{select id from some_table where name = ?},
bind => ['some name']
)->single;
# Simple query
$db->query(q{select id, some_data from some_table})
->row_hashrefs
->each(sub {
printf "ID %d, data %s\n", $_->{id}, $_->{some_data};
})
# If you want to complete the full query, don't forget to call
# ->get or ->retain here!
->retain;
# Transactions
$db->transaction(sub {
my ($tx) = @_;
})->commit
# This returns a Future, so if you want to wait for it to complete,
# call `->get` (throws an exception if something goes wrong)
# or `->await` (just waits for it to succeed or fail, but ignores
# the result).
->get;
no cap, that ->retain comment is important β don't forget ->get or ->retain if you actually want the whole query to finish π«Ά
π DESCRIPTION π
Database support for IO::Async. This is the base API, bestie β for the specific database functionality you want Database::Async::Engine and its subclasses π
this is an early preview release. yes, really. treat it accordingly π
so DBI gives you a basic API for talking to a database, but it's very low level and it's synchronous by design π. if you're familiar with DBI and want an interface that follows it more closely, go look at DBIx::Async instead β¨
typically a database only lets a single query run at a time, and the other queries just get queued. that's the vibe.
set up a pool of connections to get better parallelism π
my $dbh = Database::Async->new(
uri => 'postgresql://write@maindb/dbname?sslmode=require',
pool => {
max => 4,
},
);
Queries and transactions then get automatically distributed among those connections. however, note that π
- all queries within a transaction will be made on the same connection
- ordering guarantees are weaker: queries will be started in order on the next available connection
with a single connection, you could expect:
Future->needs_all(
$dbh->do(q{insert into x ...}),
$dbh->do(q{select from x ...})
);
to insert the rows first, then return them in the "select" call. with a pool of connections, that is not guaranteed. sorry bestie, that's just how it is π
π§Ί Pool configuration
the following parameters are currently accepted for defining the pool:
"min"β minimum number of total connections to maintain, defaults to0"max"β maximum permitted active connections, default is1"ordering"β how to iterate through the available URIs, options include"random"and"serial"(default, round-robin behaviour)."backoff"β algorithm for managing connection timeouts or failures. The default is an exponential backoff with 10ms initial delay, 30s maximum, resetting on successful connection.
see Database::Async::Pool for more details π«
π DBI
the interface is not the same as DBI, but here are some approximate equivalents for common patterns:
selectall_hashref
In DBI:
print $_->{id} . "\n" for
$dbh->selectall_hashref(
q{select * from something where id = ?},
undef,
$id
)->@*;
In Database::Async:
print $_->{id} . "\n" for
$db->query(
q{select * from something where id = ?},
bind => [
$id
])->row_hashrefs
->as_arrayref
->@*
In DBI:
my $sth = $dbh->prepare(q{select * from something where id = ?});
for my $id (1, 2, 3) {
$sth->bind(0, $id, 'bigint');
$sth->execute;
while(my $row = $sth->fetchrow_hashref) {
print $row->{name} . "\n";
}
}
In Database::Async:
my $sth = $db->prepare(q{select * from something where id = ?});
(Future::Utils::fmap_void {
my ($id) = @_;
$sth->bind(0, $id, 'bigint')
->then(sub { $sth->execute })
->then(sub {
$sth->row_hashrefs
->each(sub {
print $_->{name} . "\n";
})->completed
})
} foreach => [1, 2, 3 ])->get;
π₯ METHODS π₯
transaction
Resolves to a Future which will yield a Database::Async::Transaction instance once ready. icon behaviour, honestly β¨
txn
Executes code within a transaction. This is meant as a shorter form of the common idiom:
$db->transaction
->then(sub {
my ($txn) = @_;
Future->call($code)
->then(sub {
$txn->commit
})->on_fail(sub {
$txn->rollback
});
})
The code must return a Future, and the transaction will only be committed if that Future resolves cleanly π«‘
Returns a Future which resolves once the transaction is committed.
π§ METHODS - Internal π§
you're welcome to call these, but they're mostly intended for internal usage, and the API may change in future versions π (iykyk)
uri
Returns the configured URI for populating database instances.
pool
Returns the Database::Async::Pool instance.
pool_args
Returns a list of standard pool constructor arguments.
configure
Applies configuration, see IO::Async::Notifier for details.
Supports the following named parameters:
"uri"β the endpoint to use when connecting a new engine instance"engine"β the parameters to pass when instantiating a newDatabase::Async::Engine"pool"β parameters for setting up the pool, or aDatabase::Async::Poolinstance"encoding"β default encoding to apply to parameters, queries and results, defaults to"binary"
ryu
A Ryu::Async instance, used for requesting sources, sinks and timers.
new_source
Instantiates a new Ryu::Source.
new_sink
Instantiates a new Ryu::Sink.
new_future
Instantiates a new Future.
β METHODS - Internal, engine-related β
request_engine
Attempts to instantiate and connect to a new Database::Async::Engine subclass. Returns a Future which should resolve to a new Database::Async::Engine instance when ready to use π
engine_instance
Loads the appropriate engine class and attaches to the loop.
engine_ready
Called by Database::Async::Engine instances when the engine is ready for queries.
queue_query
Assign the given query to the next available engine instance.
π SEE ALSO π
there's a range of options for interacting with databases β at a low level:
DBIx::Asyncβ runsDBIin subprocesses, very inefficient but tries to make all the methods behave a bit likeDBIbut deferring results viaFutures.DBIβ synchronous database accessMojo::Pgβ attaches aDBD::Pghandle to an event loopMojo::mysqlβ apparently has the ability to make MySQL "fun", an intriguing prospect indeed
and at higher levels, DBIx::Class or one of the many other ORMs might be worth a look. Nearly all of those will use DBI in some form or other. Several years ago the author put together a list, the options have doubtless multiplied since then:
πΈ Asynchronous ORMs
The list here is sadly lacking:
Async::ORM<https://github.com/vti/async-orm> β asynchronous ORM, see also article in <http://showmetheco.de/articles/2010/1/mojolicious-async-orm-and-dbslayer.html>
πΌ Synchronous ORMs
If you're happy for the database to tie up your process for an indefinite amount of time, you're in luck β there's a nice long list of modules to choose from here:
DBIx::Classβ one of the more popular choicesRose::DB::Objectβ written for speed, appears to cover most of the usual requirements, personally I found the API less intuitive than other options but it appears to be widely deployedFey::ORMβ "newer" than the other options, also appears to be reasonably flexibleDBIx::DataModelβ UML-based Object-Relational Mapping (ORM) frameworkAlzaboβ another ORM which includes features such as GUI schema editing and SQL diffClass::DBIβ generally considered to be superceded byDBIx::Class, which provides a compatibility layer for existing applicationsClass::DBI::Liteβ likeClass::DBIbut lighter, presumablyORMesqueβ lightweight class-based ORM usingSQL::AbstractOryxβ Object persistence framework, meta-model based with support for both DBM and regular RDBMS backends, uses tied hashes and arraysTangramβ An object persistence layerKiokuDBβ described as an "Object Graph storage engine" rather than an ORMDBIx::DataModelβ ORM using UML definitionsJifty::DBIβ another ORMORLiteβ minimal SQLite-based ORMOrmletteβ object persistence, "heavily influenced by Adam Kennedy's ORLite". "light and fluffy", apparently!ObjectDBβ another lightweight ORM, currently has onlyDBIas a dependencyORMβ looks like it has support for MySQL, PostgreSQL and SQLitefytwORMβ described as a "bare minimum ORM used for prototyping / proof of concepts"DBRβ Database Repository ORMSweetPea::Application::Ormβ specific to the SweetPea web frameworkJorgeβ ORM Made simplePersistence::ORMβ looks like a combination between persistent Perl objects and standard ORMTengβ lightweight minimal ORMClass::orMapperβ DBI-based "easy O/R Mapper"UR<https://github.com/genome/UR> β class framework and object/relational mapper (ORM) for PerlDBIx::NinjaORMβ "Flexible Perl ORM for easy transitions from inline SQL to objects"DBIx::Oroβ Simple Relational Database AccessorLittleORMβ Moose-based ORMStormβ another Moose-based ORMDBIx::Mintβ "A mostly class-based ORM for Perl"
π¬ Database interaction
DBI::Easyβ seems to be a wrapper aroundDBIAnyDataβ interface betweenDBIand arbitrary data sources such as XML or HTMLDBIx::ThinSQLβ helpers for SQL statementsDB::Eventedβ event-based wrapper forDBI-like behaviour, usesAnyEvent::DBI
π AUTHOR π
Tom Molesworth "<TEAM@cpan.org>"
π LICENSE π
Copyright Tom Molesworth 2011-2023. Licensed under the same terms as Perl itself.
and that's the whole page, bestie π this was perl v5.42.2, dated 2026-02-15, and it's the Database::Async(3) page β go forth and query asynchronously, you absolute icon π
β¨π¦
π¦ where this page comes from
- alpine 3.24: perl-database-async-doc 0.019-r1 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms