使用DBIx :: Class,如何检查表是否存在?

时间:2013-05-18 14:10:14

标签: perl dbix-class

我的目标是创建一个函数,如果尚未创建,我将创建我的MySQL数据库表(使用已通过DBIx :: Class定义的模式)。否则,它只是创建对$ schema的引用。

目前我了解如何使用以下代码创建表:

my $schema = MyApp::Schema->connect(
   $dsn,
   $user,
   $password,
 );

$schema->deploy( { add_drop_table => 1 } );

我需要为此添加更多逻辑,以便它不会尝试添加表(如果它已经存在)。

3 个答案:

答案 0 :(得分:1)

如果您只想每次都创建它,可以在create table语句中使用“Drop Table If Exists”。如果您不想弄乱数据,那么您可以随时执行“显示表格”并解析结果,例如

my $tables = $dbh->selectall_arrayref(qq|Show tables|) or die "Can't show tables " . $dbh->errstr();
if (@$tables) { 
   foreach my $table (@$tables) {   
      if ($table->[0] eq 'sometablename') {
         # Table sometablename exists
      }
   }
}

答案 1 :(得分:1)

这可能不是最便宜的支票(特别是对于一些DB),但对于DBIC来说有些惯用。

my $schema = MySchema->connect(...);

for my $source_name ( $schema->sources )
{
    eval { $schema->resultset($source_name)->count };
    print $source_name, " is ", $@ ? "missing? $@" : "OK\n";
}

更新,这有点笨拙(rejigger rows / single / first / all),但它具有相当便宜的优点。

eval {
    $schema->resultset($source_name)
        ->search({},
                 { where => \q{ 1 = 0 },
                   rows => 1 })
        ->single;
};

答案 2 :(得分:1)

我最终这样做了,其中$ schema是一个全局变量。 由于使用show tables,此解决方案仅适用于MySQL (据我所知)。

sub tableExists {
    my $table = shift;
    my $dbh   = $schema->storage->dbh;    # Get our DBI handle.

    my $sql    = "show tables like '$table'"; #MySQL only
    my $sth    = $dbh->prepare($sql);
    my $exists = undef;
    if ( $sth->execute() ) {

        while ( my $t = $sth->fetchrow_array() ) {
            print $t, $/;
            if ( $t =~ /^$table$/ ) { $exists = 1; }

        }
    }

    if ( defined $exists ) {
        print "found\n";
        return $exists;
    }
    else {
        print "not found\n";
        return $exists;
    }
}

我称之为:

$schema = MyApp::Schema->connect(
   $dsn,
   $user,
   $password,
 );

my $table_exists = tableExists("mytable");

if ( !defined $table_exists ) {
    print "Deploying schema...", $/;
    $schema->deploy();
    print "Done", $/;
}