2

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

目前我了解如何使用以下代码创建表,如果它不存在:

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

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

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

4

3 回答 3

1

我最终这样做了,其中 $schema 是一个全局变量。由于使用了show tables.

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", $/;
}
于 2013-05-22T03:59:51.323 回答
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
      }
   }
}
于 2013-05-18T14:27:03.523 回答
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";
}

更新,这有点笨拙(重新调整行/单/第一/全部由您随意),但它具有相当便宜的优点。

eval {
    $schema->resultset($source_name)
        ->search({},
                 { where => \q{ 1 = 0 },
                   rows => 1 })
        ->single;
};
于 2013-05-20T16:27:44.400 回答