как получить одну строку для каждой таблицы с Perl $ dbh- ›таблицами?

Я хочу получить информацию о схеме базы данных sqlite, как это делает .schema, но с Perl DBI. Первая попытка заключалась в том, чтобы получить имена таблиц с $dbh->tables, но я получаю повторяющиеся имена таблиц. Это одна запись для самой таблицы и одна запись для каждого индекса, который у меня есть (table_a имеет 3 индекса и b один), каково обоснование этого ?.

DB<7> x $dbh->tables;
0  '"main"."table_a"'
1  '"main"."table_a"'
2  '"main"."table_a"'
3  '"main"."table_b"'
4  '"main"."sqlite_master"'
5  '"temp"."sqlite_temp_master"'
6  '"main"."table_a"'
7  '"main"."table_b"'

Я был бы признателен, если бы кто-нибудь мог дать подсказку по этим трем связанным вопросам: как получить только таблицы (без выполнения uniq) и почему для каждого индекса есть одна строка? Как я могу получить информацию об индексах? и все вместе, как получить эквивалентную информацию для .schema?

[обновлено] Я видел это на DBI 1.627

@names = $dbh->tables;        # deprecated

Но не упоминается почему.

и они предлагают использовать

@names = $dbh->tables( $catalog, $schema, $table, $type );

но после прочтения DBI table_info, где объясняются эти параметры, я не совсем понял, как заполнить их для получения информации о таблицах, чтобы получить имена таблиц только один раз или, если возможно получить все это, ту же информацию, что с .schema.

Любой пример или ссылка на более подробное использование будут оценены.

[[ОБНОВЛЕНИЕ]] на всякий случай, это две проблемы, которые помешали мне найти ответ самостоятельно, прежде чем задать здесь вопрос:

1- Google направил меня на очень старую страницу документации DBD-sqlite, на которой почти ничего не было, и я не обратил внимания на ссылку на последний выпуск в верхней части страницы.

2- Прежде чем спрашивать здесь, я читал в других потоках о table_info (правильный ответ), но, несколько лет не писав кода DBI, я попал в одну из ловушек для новичков. Поскольку $ dbh-> tables возвращает массив, я не обращал внимания на то, что table_info возвращает обработчик оператора, поэтому, когда я попробовал x $dbh->table_info(...) в отладчике и получил пустой хеш, я застрял. Я забыл о необходимости вызывать часть выборки для возвращаемого $ sth.


person Pablo Marin-Garcia    schedule 15.07.2013    source источник


Ответы (2)


Как получить только таблицы (без выполнения uniq)

Я полагаю, что $dbh->tables интерфейс слишком прост, чтобы отражать сложность механизмов SQL и различных драйверов. Как вы заметили, вместо этого следует использовать table_info().

В частности, см. Документацию DBD :: SQLite для table_info() (v1.39 на момент написания), поскольку в документации DBD можно узнать, какие функции поддерживаются базой данных и драйвером (например, SQLite не имеет каталогов). Что-то вроде этого даст вам то, что вы хотите:

use feature qw(say);
...

# Get info on every ('%') TABLE entity in the "main" schema.  Catalog is blank
# b/c DBD::SQLite and/or SQLite itself has no concept of catalogs.
my $sth = $dbh->table_info('', 'main', '%', 'TABLE');

while (my $r = $sth->fetchrow_hashref) {   # outputs:  table_a
  say $r->{TABLE_NAME};                    #           table_b
}

и почему для каждого индекса есть одна строка?

Неуверенно, но вероятно случайность tables() простого интерфейса. Опять же, используйте table_info() для перечисления таблиц и табличных объектов.

Как получить информацию об индексах?

Экспериментальный statistics_info() метод может поддерживаться.

и все вместе, как получить информацию, эквивалентную .schema?

Тебе повезло. Драйвер DBD :: SQLite предоставляет table_info поле расширения 'sqlite_sql', которое для меня дает операторы «CREATE TABLE ...» за каждой таблицей. (Также то, что я получаю от .schema.) Попробуйте:

my $sth = $dbh->table_info('', 'main', '%', 'TABLE');

while (my $r = $sth->fetchrow_hashref) {
  say $r->{sqlite_sql};
}
person pilcrow    schedule 15.07.2013
comment
черт возьми, гугл! ;-). Я пошел на DBD-sqlite от Google и закончил на search.cpan.org/~msergeant/DBD-SQLite-0.31/lib/DBD/SQLite.pm и информации там почти не было. Я собирался спросить вас, откуда вы получили информацию, и, просканировав все углы страницы, я понял, что в верхней строке моей страницы dbd-sqlite был «последний выпуск 1.39». Теперь я на нужной странице документации. Спасибо за ваши примеры и за то, что помогли мне понять, что я попал не на ту страницу с документами. - person Pablo Marin-Garcia; 15.07.2013

Как перечислить названия таблиц:

my $sth=$dbh->table_info('','main','%', 'TABLE')
my $tables = [map{$_->[2]} @{$sth->fetchall_arrayref()}];
say join("\n", @$tables);
person Pablo Marin-Garcia    schedule 16.07.2013