2013-05-18 1 views
2

Моя цель - создать функцию, которая создаст мою MySQL-таблицу db (используя схему, определенную через DBIx :: Class уже), если она еще не была создана. В противном случае он просто создает ссылку на $ schema.Использование DBIx :: Class, как проверить, существует ли таблица?

В настоящее время я понимаю, как создать таблицу, если она не существует со следующим кодом:

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

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

мне нужно добавить больше логики к этому так, что она не будет пытаться добавить таблицу, если он уже существует.

+1

http://lists.scsys.co.uk/pipermail/dbix-class/2009-March/007494.html и HTTP: // lists.scsys.co.uk/pipermail/dbix-class/2009-March/007495.html –

ответ

1

Я закончил тем, что сделал это так, где $ schema - глобальная переменная. Это решение работает только для MySQL (как я понимаю) из-за использования 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", $/; 
} 
1

Вы можете использовать «Drop Table If Exists» в инструкции create table, если вы просто хотите ее создать каждый раз. Если вы не хотите возиться с данными, то вы всегда можете сделать «Показать таблицы» и анализировать результаты, что-то вроде

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

Это может быть не самый дешевый чек (особенно с некоторой БД), но несколько идиоматический для DBIC.

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

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

Update, и это немного неуклюжий (rejigger строк/один/первый/все в свое удовольствие), но он имеет силу того, что довольно дешево.

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