mns
mns

Reputation: 77

Use DBIx::Class with a single result class definition to handle several tables with the same structure

I have several (~100 and counting) MySQL tables with more than 50M entries each. The thing is that all this tables have exactly the same structure and I would like to create a single result class for them in DBIx::class. For example consider a bunch of tables of the following structure:

CREATE TABLE users_table_1 (
  name TINYTEXT,
  username TINYTEXT
);
CREATE TABLE users_table_2 (
  name TINYTEXT,
  username TINYTEXT
);
...

I would like to be able to do the following without having to create a result class for each one of the tables.

my $users_1_rs = $schema->resultset('User_table_1');
my $users_2_rs = $schema->resultset('User_table_2');
...

I am new to DBIx::Class and the only two possible solutions that I could come up with are:

  1. For each of the tables use something like DBIx::Class::DynamicSubclass to subclass from a base result class with all common functionality. The disadvantage is that this way I still need to write a class (although a small one) for every single one of my tables.
  2. Use DBIx::Class::Loader and create the classes automatically from the database itself. However, I don't find this solution very elegant and robust for my needs.

Could someone point me to a more elegant solution for this problem?

Upvotes: 1

Views: 554

Answers (2)

draegtun
draegtun

Reputation: 22560

There is probably a metaprogramming API within DBIx::Class for dynamically creating table classes.

In lieu of delving into the (rather large DBIx::Class) docs here is an alternative example creating the classes in plain Perl metaprogramming:

package MySchema;
use strict;
use warnings;
use parent 'DBIx::Class::Schema';

our @tables = map { 'users_table_' . $_ } 1..2;

require DBIx::Class::Core;

# build table classes for users_tables_*
for my $table (@MySchema::tables) {
    my $t = "MySchema::$table";
    {
        no strict 'refs';
        @{$t . '::ISA'} = qw/DBIx::Class::Core/;
    }
    $t->table($table);
    $t->add_columns(qw/name username/);
}

__PACKAGE__->load_classes(@MySchema::tables);

1;

In my simple tests the above worked for me :)

Upvotes: 2

alex
alex

Reputation: 1304

I would sugest using "from" parameter in search function:

...resultset('TableA')->search({}, { from=>'TableB'});

Upvotes: 0

Related Questions