Pg meta data: примеры (PHP)
pg_meta_data(PgSql\Connection $connection, string $table_name, bool $extended = false): array|falseФункция pg_meta_data в PHP используется для получения метаинформации о таблицах в базе данных PostgreSQL. Она возвращает массив, описывающий столбцы указанной таблицы, включая их имена, типы данных, длину, атрибуты и другие свойства.
Функция применяется для динамического анализа структуры таблицы, что полезно при генерации форм, валидации данных, создании инструментов администрирования или ORM-систем. Она позволяет получить информацию о типах полей без написания прямых SQL-запросов к системным каталогам.
array pg_meta_data(PgSql\Connection $connection, string $table_name, bool $extended = false): array
- $connection (обязательный): Объект соединения с PostgreSQL, полученный с помощью функций pg_connect() или pg_pconnect().
- $table_name (обязательный): Имя таблицы, для которой запрашивается метаинформация. Имя может включать имя схемы (например, 'public.users').
- $extended (опциональный): Флаг, определяющий детализацию возвращаемой информации. При значении false возвращаются основные сведения (имя, тип, длина, возможность NULL). При значении true добавляется информация о модификаторах (таких как not null, первичный ключ) и значениях по умолчанию.
Функция возвращает ассоциативный массив, где ключи - имена столбцов, а значения - массивы с их характеристиками. В случае ошибки возвращается false.
<?php
$conn = pg_connect('host=localhost dbname=test user=postgres');
$meta = pg_meta_data($conn, 'users');
print_r($meta);
?>
Array
(
[id] => Array
(
[type] => int4
[len] => 4
[not null] => 1
[has default] => 1
)
[name] => Array
(
[type] => varchar
[len] => 255
[not null] =>
[has default] =>
)
)
<?php
$meta = pg_meta_data($conn, 'orders', true);
print_r($meta['order_date']);
?>
Array
(
[type] => date
[len] => 4
[not null] => 1
[has default] =>
[array] =>
[enum] =>
[pkey] =>
[default] =>
)
<?php
$meta = pg_meta_data($conn, 'public.products');
?>В PHP существуют другие функции для работы с метаданными баз данных.
Функция pg_field_info возвращает информацию о конкретном столбце в результате запроса. Она используется после выполнения запроса с помощью pg_query().
<?php
$result = pg_query($conn, 'SELECT * FROM users');
$info = pg_field_info($result, 0); // информация о первом столбце
?>
Функция pg_meta_data предпочтительнее для получения структуры таблицы без выполнения запроса на выборку данных, тогда как pg_field_info подходит для анализа столбцов уже выполненного запроса.
При использовании расширения PDO метод getColumnMeta предоставляет метаинформацию о столбце в результирующем наборе. Он не специфичен для PostgreSQL и работает с различными СУБД.
<?php
$stmt = $pdo->query('SELECT * FROM users');
$meta = $stmt->getColumnMeta(0);
?>
PDO является более универсальным и современным подходом, но pg_meta_data предлагает более детализированную информацию именно для PostgreSQL.
import psycopg2
conn = psycopg2.connect('dbname=test')
cursor = conn.cursor()
cursor.execute('''
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = 'users'
''')
for col in cursor.fetchall():
print(col)
('id', 'integer', 'NO')
('name', 'character varying', 'YES')
В Python аналогом является прямой запрос к системным представлениям information_schema или pg_catalog. Функции, аналогичной pg_meta_data, в psycopg2 нет.
const { Client } = require('pg');
const client = new Client();
(async () => {
await client.connect();
const res = await client.query(`
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = 'users'
`);
console.log(res.rows);
})();
Аналогично Python, в Node.js метаданные получают через запросы к information_schema.
DESCRIBE users;
-- Или
SHOW COLUMNS FROM users;
В MySQL используются специальные SQL-команды, а не отдельная функция в языке программирования.
<?php
$meta = pg_meta_data($conn, 'non_existent_table');
if ($meta === false) {
echo 'Ошибка получения метаданных. Таблица может не существовать.';
}
?>
Ошибка получения метаданных. Таблица может не существовать.
<?php
$meta = pg_meta_data('not a connection', 'users'); // Предупреждение
?>
Это приводит к предупреждению PHP и возврату false.
Если пользователь базы данных не имеет прав на чтение таблицы, функция вернет false. Необходимо проверить привилегии.
<?php
$meta = pg_meta_data($conn, 'users');
var_dump($meta); // bool(false)
?>В PHP 8.0 изменен тип возвращаемого значения при ошибке. Раньше функция могла вернуть false или массив. Теперь в случае ошибки выбрасывается исключение типа Exception. Это соответствует общей тенденции PHP 8 к более строгой обработке ошибок.
Обновлен тип параметра $connection: теперь ожидается объект PgSql\Connection вместо ресурса (resource). Это связано с переходом на объектно-ориентированный API для расширений баз данных.
<?php
// PHP 7 (ресурс)
$conn = pg_connect(...);
// PHP 8 (объект PgSql\Connection)
$conn = pg_connect(...); // Возвращает объект PgSql\Connection
?><?php
$table = 'users';
$meta = pg_meta_data($conn, $table, true);
if ($meta) {
echo '<form>';
foreach ($meta as $column => $info) {
echo '<div>';
echo '<label>' . htmlspecialchars($column) . '</label>';
$type = $info['type'];
if (strpos($type, 'int') !== false) {
echo '<input type="number" name="' . $column . '">';
} elseif (strpos($type, 'varchar') !== false) {
echo '<input type="text" name="' . $column . '" maxlength="' . $info['len'] . '">';
} else {
echo '<input type="text" name="' . $column . '">';
}
echo '</div>';
}
echo '</form>';
}
?>
<?php
function compareTables($conn, $table1, $table2) {
$meta1 = pg_meta_data($conn, $table1);
$meta2 = pg_meta_data($conn, $table2);
$diff = [];
foreach ($meta1 as $col => $info1) {
if (!isset($meta2[$col])) {
$diff['only_in_' . $table1][] = $col;
} elseif ($info1['type'] !== $meta2[$col]['type']) {
$diff['type_mismatch'][$col] = [$info1['type'], $meta2[$col]['type']];
}
}
return $diff;
}
?>
<?php
function validateInsertData($conn, $table, $data) {
$meta = pg_meta_data($conn, $table, true);
$errors = [];
foreach ($meta as $column => $info) {
if ($info['not null'] && empty($data[$column]) && !$info['has default']) {
$errors[] = "Поле $column обязательно для заполнения.";
}
}
return $errors;
}
?>
<?php
// Для таблицы с полем типа point
$meta = pg_meta_data($conn, 'geo_objects', true);
print_r($meta['coordinates']);
?>
Array
(
[type] => point
[len] => -1
[not null] =>
[has default] =>
[array] =>
[enum] =>
[pkey] =>
[default] =>
)