官方文档给出了多种连接presto的客户端,目前我尝试了常用的三种:命令行客户端、通过JDBC驱动在Java中连接presto、Python客户端。这里记录三种连接方式的Demo,免得以后又得在网上找了试半天。
客户端的执行没有系统环境要求,只要安装了对应的依赖项就可以。这次实验是基于上一篇文章搭建的环境进行的,presto的coordinator和worker都安装在同一个机器上(ubuntu16.04)。我在ubuntu16.04下验证命令行界面,在window10下验证Java JDBC连接和Python客户端连接。
命令行界面
Presto CLI介绍:提供基于命名行的交互界面用户向presto提交查询,presto CLI是1个jar包,因此需要启动客户端的机器已经安装有jvm虚拟机(>=java 1.8即可)。
环境:ubuntu 16.04 LTS + open-jdk 1.8
-
下载presto-cli-0.242-executable.jar, 重命名为
presto并通过chmod +x将其设置为可执行文件。 -
启动命令:
# 参数server: coordinator的URI
# 参数catalog: 启用哪个数据源配置文件
# 参数schema:
sudo ./presto --server localhost:8080 --catalog demo --schema default
- 执行查询:
select * from demo.blog_master_db.article union all select * from demo.blog_worker_db.article;
- 执行结果:可以看到1个SQL语句中将两个数据库
blog_master_db和blog_worker_db的数据都查出来了。
Java JDBC连接
JDBC驱动介绍:允许用户在基于Java开发的应用或者在JVM上运行的非Java应用连接Presto。
环境:win10 + jdk 1.8 + maven 3.3.9 + idea 2019.2.4
- 使用idea创建1个空的maven工程。
- 在创建的maven工程的pom.xml文件中引入presto的jdbc驱动
<dependencies>
<!--Presto JDBC Driver-->
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-jdbc</artifactId>
<version>0.242</version>
</dependency>
</dependencies>
- 在Java代码中测试
import java.sql.*;
import java.util.Properties;
public class PrestoJdbcDemo {
public static void main(String[] args) throws SQLException {
// url的命名格式:jdbc:presto://host:port/catalog/schema
// 其中catalog和schema可以省略.
// 1.省略catalog和schema时, 执行sql中必须用catalog.schema.table的形式指定表
// String url = "jdbc:presto://192.168.18.128:8080";
// String sql = "select * from demo.blog_master_db.article union all select * from demo.blog_worker_db.article";
// 2.省略schema时, 执行sql中至少要用schema.table的形式指定表(默认用指定的catalog)
String url = "jdbc:presto://192.168.18.128:8080/demo";
String sql = "select * from blog_master_db.article union all select * from blog_worker_db.article";
// 3.url包含catalog和schema, 执行sql可直接用table名(默认用指定的catalog.schema)
// String url = "jdbc:presto://192.168.18.128:8080/demo/default";
// String sql = "select * from blog_master_db.article union all select * from blog_worker_db.article";
Properties properties = new Properties();
properties.setProperty("user", "random"); //如果没有作权限控制, 用户名可以随便填写
properties.setProperty("password", ""); //如果没有作权限控制, 密码可以为空
// properties.setProperty("SSL", "true"); //如果没有作权限控制, 需要注释改行
try{
Connection connection = DriverManager.getConnection(url, properties);
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int Id = rs.getInt("ID");
String Name = rs.getString("NAME");
int viewNum = rs.getInt("VIEW_NUM");
int comNum = rs.getInt("COM_NUM");
String channel = rs.getString("CHANNEL");
System.out.println(Id + "\t" + Name + "\t" + viewNum + "\t" + comNum + "\t" + channel);
}
rs.close();
connection.close();
}catch(Exception e){
System.out.println("Exception detected: " + e);
}finally {
}
}
}
- 执行结果:
Python客户端
目前有两个Python客户端可以连接presto:presto官方维护的presto-python-client,第三方维护的PyHive。PyHive的用户更多,而且可以结合SQLAlchemy使用。
presto-python-client
环境:win10 + python 3.6
- 安装:
pip install presto-client - 基于Python的DB-API连接presto
import presto
# demo about the usage of presto-python-client
conn = presto.dbapi.connect(
host='192.168.18.128',
port=8080,
user='random',
catalog='demo',
schema='default'
)
cur = conn.cursor()
sql = 'select * from blog_master_db.article union all select * from blog_worker_db.article'
cur.execute(sql)
rows = cur.fetchall()
print(rows)
- 查询结果:结果为python的
list
PyHive
环境:win10 + python 3.6
- 安装:
pip install pyhive
PyHive连接presto有两种方式:使用python DB-API,结合SQLAlchemy。
DB-API
- 与presto-pyhon-client基本相同,只有个别参数名不同:
from pyhive import presto
# demo about the usage of pyhive
conn = presto.connect(
host='192.168.18.128',
port=8080,
username='random',
catalog='demo',
schema='default'
)
cursor = conn.cursor()
sql = 'select * from blog_master_db.article union all select * from blog_worker_db.article'
cursor.execute(sql)
print(cursor.fetchall())
- 查询结果:结果为python的
list
SQLAlchemy
- 安装SQLAlchemy:
conda install sqlalchemy - python代码
# pyhive + sqlalchemy + pandas
from sqlalchemy.engine import create_engine
import pandas as pd
# host是服务器ip, port是端口, demo指的是Presto的catalog,default是demo的schema
engine = create_engine('presto://192.168.18.128:8080/demo/default')
# 和一般pandas从数据库中读取数据无任何区别
sql = 'select * from blog_master_db.article union all select * from blog_worker_db.article'
df = pd.read_sql(sql, engine)
print(df)
- 查询结果:由于使用了pandas,查询结果为dataFrames