Я пытаюсь подключиться к Snowflake через их драйвер ODBC в PHP (CentOS 6 и 7) и использовать PDO для более легкого доступа.
Драйвер ODBC, похоже, установлен и работает должным образом, так как встроенные функции ODBC в PHP работают довольно хорошо:
$dsn = "Driver=SnowflakeDSIIDriver;Server=" . SNOWFLAKE_HOST;
$dsn .= ";Account=" . SNOWFLAKE_ACCOUNT;
$dsn .= ";Port=" . SNOWFLAKE_PORT;
$dsn .= ";Schema=" . SNOWFLAKE_SCHEMA;
$dsn .= ";Warehouse=" . SNOWFLAKE_WAREHOUSE;
$dsn .= ";Database=" . SNOWFLAKE_DATABASAE;
$conn_id = odbc_connect($dsn, SNOWFLAKE_USER, SNOWFLAKE_PASSWORD);
odbc_exec($conn_id, "USE WAREHOUSE " . SNOWFLAKE_WAREHOUSE);
$res = odbc_exec($conn_id, 'SHOW TABLES IN SCHEMA ' . SNOWFLAKE_SCHEMA . ';');
if ($res) {
print "Tables in schema\n";
while($row = odbc_fetch_array($res)) {
print_r($row);
}
}
$res = odbc_exec($conn_id, 'SELECT * FROM TEST;');
if ($res) {
print "Test table content\n";
while($row = odbc_fetch_array($res)) {
print_r($row);
}
}
возвращается
Tables in schema
Array
(
[created_on] => 2015-09-09 17:34:43.517000
[name] => TEST
[database_name] => TESTSUITE
[schema_name] => TESTSUITE
[kind] => TRANSIENT
[comment] =>
[cluster_by] =>
[rows] => 3
[bytes] => 8192
[owner] => TESTSUITE
[account_name] => ****
[retention_time] => 1
)
Test table content
Array
(
[C1] => c
[C2] =>
)
Array
(
[C1] => a
[C2] =>
)
Array
(
[C1] => a
[C2] =>
)
и это именно то, что я получаю, когда обращаюсь напрямую к БД.
Но когда я хочу использовать PDO, результаты становятся странными.
$dsn = "Driver=SnowflakeDSIIDriver;Server=" . SNOWFLAKE_HOST;
$dsn .= ";Account=" . SNOWFLAKE_ACCOUNT;
$dsn .= ";Port=" . SNOWFLAKE_PORT;
$dsn .= ";Schema=" . SNOWFLAKE_SCHEMA;
$dsn .= ";Database=" . SNOWFLAKE_DATABASE;
$dsn .= ";Warehouse=" . SNOWFLAKE_WAREHOUSE;
$pdo = new PDO("odbc:" . $dsn, SNOWFLAKE_USER, SNOWFLAKE_PASSWORD, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$pdo->exec("USE WAREHOUSE " . SNOWFLAKE_WAREHOUSE);
$query = 'SHOW TABLES IN SCHEMA ' . SNOWFLAKE_SCHEMA . ';';
$statement = $pdo->query($query);
print "Tables in schema\n";
print "Rows: " . $statement->rowCount() . "\n";
while ($row = $statement->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
print_r($row);
}
$query = 'SELECT * FROM TEST;';
$statement = $pdo->prepare($query);
$statement->execute();
print "Test table content\n";
print "Rows: " . $statement->rowCount() . "\n";
while ($row = $statement->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
print_r($row);
}
возвращается
Tables in schema
Rows: 1
Array
(
[created_on] => 2015-09-09 17:34:43.517000
[name] =>
[database_name] =>
[schema_name] =>
[kind] =>
[comment] =>
[cluster_by] =>
[rows] =>
[bytes] =>
[owner] =>
[account_name] =>
[retention_time] =>
)
Test table content
Rows: 3
Примечание: после вывода больше нет Rows: 3
,
Таким образом, PDOStatement знает правильное количество строк, но содержание SHOW TABLES
неполный и SELECT * FROM TEST
как-то отсутствует полностью ($statement->fetch()
возвращается false
немедленно).
Любая идея, если какие-либо варианты PDO помогут здесь?
Я также заметил, что в этом случае встроенные функции ODBC потребляют ~ 200 МБ памяти, что, похоже, очень много.
У нас была похожая проблема, когда CAST некорректно работал через PDO со Snowflake.
исключение «PDOException» с сообщением «SQLSTATE [SL009]: <>: 0 [unixODBC] [Driver Manager] Ни один столбец не был связан до
вызов SQLFetch или SQLFetchScroll
Короче говоря, после обмена парой писем с поддержкой Snowflake, мы обнаружили, что PDO не поддерживается Snowflake.
В настоящее время мы не поддерживаем PHP PDO из-за некоторых проблем.
найдено из-за привязки типа STRING / VARCHAR и размера столбцов
16 миллионов байт. Это было решение не двигаться вперед с поддержкой.
Вы можете продолжать использовать PHP с ODBC, однако мы не сможем
решать проблемы / ошибки по мере их возникновения.
Так что лучше всего использовать родную odbc_*
семейство функций из PHP (это то, что мы делаем).
Других решений пока нет …