bozerkins / clickhouse-client
简单的PHP Clickhouse客户端
Requires
- php: >=7.0
- ext-curl: *
- ext-json: *
- symfony/options-resolver: >=2.8
Requires (Dev)
- phpunit/phpunit: ^6.2
- symfony/var-dumper: >=2.8
README
这是一个简单的Clickhouse客户端版本(使用HTTP接口)。这个版本提供了对HTTP接口的最接近的访问,允许你在PHP应用中最大限度地使用Clickhouse数据库的能力。
安装
使用composer进行基本安装
composer require bozerkins/clickhouse-client
配置
use ClickhouseClient\Client\Config; $config = new Config( // basic connection information ['host' => '127.0.0.1', 'port' => '8123', 'protocol' => 'http'], // settings ['database' => 'default'], // credentials ['user' => 'default', 'password' => ''] );
您可以在第二个参数中传递额外的设置,包括数据库名称。
完整的设置列表可以在Clickhouse文档的设置部分中找到。
如果您使用默认配置,则不需要定义所有这些设置。
例如,如果您需要创建一个只读访问的客户端对象,请传递 "readonly" 参数。
$config = new Config( // basic connection information - set to default [], // settings [ 'database' => 'my_shiny_database', 'readonly' => 1 ] // credentials - set to defauult [] );
与Clickhouse数据库的通信使用php-curl库。如果您想更紧密地控制查询执行,可以在Config构造函数中传递第四个参数,包含php-curl库的参数。
例如,如果我们想设置5秒的连接超时,我们将创建以下配置
use ClickhouseClient\Client\Config; $config = new Config( // basic connection information - set to default [], // settings [ 'database' => 'my_shiny_database', 'readonly' => 1 ] // credentials - set to defauult [], // additional CURL options [ CURLOPT_TIMEOUT => 5 ] );
支持的常量完整列表可以在curl_setopt函数文档中找到。
您可以在创建配置对象之后定义凭据或设置
use ClickhouseClient\Client\Config; $config = new Config( // basic connection information ['host' => '127.0.0.1', 'port' => '8123', 'protocol' => 'http'] ); $config->setUser('user'); $config->setPassword('password'); $config->change('database', 'new-db');
尚未实现更改基本连接信息和curl设置的功能,因为从概念上和技术上讲,更改这些设置应被视为一个新的客户端。
客户端
创建客户端相对简单。
use ClickhouseClient\Client\Client; $client= new Client($config);
从Clickhouse读取
从Clickhouse读取数据有几种方法。
简单查询
此方法主要用于从Clickhouse获取统计数据、聚合数据。
# perform select $response = $client->query( 'SELECT * FROM system.numbers LIMIT 10' ); # get decoded output - database response $response->getContent(); # get raw output string - raw string received from clickhouse $response->getOutput(); # get communication details - curl defails for the request $response->getDetails(); # and a neat shortcut for getting http response code $response->getHttpCode();
每个客户端查询返回一个响应,其中包含有关执行连接和响应的所有信息。
将查询数据流入流
可以将数据直接从Clickhouse读取到流中,例如文件。
# create a stream - open a file $stream = fopen('/tmp/file-to-read-data-into', 'r+'); # query data into the file $client->queryStream( "SELECT * FROM system.numbers LIMIT 5", $stream );
将查询数据流入闭包(函数可调用)
此方法在您打算将一个Clickhouse响应分割到几个目的地时非常有用。
# open file 1 $file1 = fopen('/tmp/file-to-read-data-into-1', 'r+'); # open file 2 $file2 = fopen('/tmp/file-to-read-data-into-2', 'r+'); # query data, process response with anonymous function $client->queryClosure( "SELECT * FROM system.numbers LIMIT 100", function($line) use ($file1, $file2) { $row = json_decode($line); if ($row['number'] % 2 === 0) { fwrite($file1, $line . PHP_EOL); } else { fwrite($file2, $line . PHP_EOL); } } );
向Clickhouse写入
向数据库写入也有几种方式。
简单插入
写入数据库的最常见方式。
# write data to a table $client->write('INSERT INTO myTable VALUES (1), (2), (3)');
注意:clickhouse没有像MySQL / Oracle / 等.那样的转义机制。为了安全插入,请参阅其他插入方法。
行插入
将数据安全且容易地插入clickhouse表的最安全和最简单的方法是使用"writeRows"方法。该方法将插入语句的前半部分作为第一个参数,将PHP数组形式的行作为第二个参数。当插入数据时,"writeRows"方法将数据编码为Clickhouse数据库可以解释的适当格式。默认情况下是JSON格式。这种方法不需要显式的转义。
# write data to a table $client->writeRows('INSERT INTO myTable', [ ['number' => 5], ['number' => 6], ['number' => 7] ] );
文件插入
另一种插入数据的方式是从文件直接插入。
注意:文件中的数据格式应与clickhouse期望的格式相匹配。
$stream = fopen('my/local/file.lines.json','r'); $client->writeStream( 'INSERT INTO t', $stream );
此方法实际上不仅接受来自文件的数据,还接受来自任何PHP流资源的数据。因此,我们可以从其他地方导入数据,例如内存(或任何可以表示为流的东西)。
# create memory stream $stream = fopen('php://memory','r+'); # write some data into it fwrite($stream, '{"a":8}'.PHP_EOL.'{"a":9}'.PHP_EOL ); # rewind pointer to the beginning rewind($stream); # insert the data $client->writeStream( 'INSERT INTO t', $stream );
系统查询
客户端对象支持系统查询。此类查询可以管理数据库模式、进程等。
# drop table $client->system('DROP TABLE IF EXISTS t'); # create table $client->system('CREATE TABLE IF NOT EXISTS t (a UInt8) ENGINE = Memory'); # kill query $client->system('KILL QUERY WHERE query_id = "SOME-QUERY-ID"');
如果在执行操作时失败,客户端将抛出异常。
也可以更改整个客户端的数据库。
# change database $client->config()->change('database', 'new-database');
它使用与创建“客户端”对象时传递的相同的配置对象,因此此代码也将正常工作。
# create config $config = new Config(); # create client $client = new Client($config); # change database $config->change('database', 'new-database');
格式
Clickhouse支持几种格式。这些格式用于检索和插入数据。默认格式设置为JSON。当执行简单的选择/插入查询时,数据将被编码为JSON,并在客户端和Clickhouse之间传输。这对于流/闭包查询/写入不适用。当执行任何查询/写入时,您可以通过传递一个类名作为最后一个参数来更改通信格式。
use ClickhouseClient\Client\Format; # select using default JSON format $client->query('SELECT * FROM system.numbers LIMIT 5'); # select using TabSeparated format $client->query('SELECT * FROM system.numbers LIMIT 5', Format\TabSeparatedFormat::class); # insert usin JSON format $client->writeRows('INSERT INTO myTable', [ ['number' => 5], ['number' => 6], ['number' => 7] ] ); # insert usin TabSeparated format $client->writeRows('INSERT INTO myTable', [ ['number' => 5], ['number' => 6], ['number' => 7] ], Format\TabSeparatedFormat::class ); # create client with differrent default format $client = new Client($config, Format\TabSeparatedFormat::class); # create client without default format (which would result in errors in some cases) $client = new Client($config, null);
Ping
Clickhouse数据库支持ping方法。
您可以使用客户端的ping方法检查数据库是否正确响应。
$client->ping();
如果出现连接问题,将抛出异常。
异常处理
客户端类发出的任何请求都可能抛出异常。
在执行查询时检查异常是一个好习惯。
use ClickhouseClient\Exception\Exception; try { $client->ping(); } catch (Exception $ex) { # get configurations of the connector $ex->getConfig(); # get repsonse $ex->getResponse(); # and get the message, ofc $ex->getMessage(); }
支持
如果库有任何问题,请在GitHub上创建问题,或通过电子邮件联系[email protected]