三种客户端连接Presto

5,892 阅读3分钟

官方文档给出了多种连接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

  1. 下载presto-cli-0.242-executable.jar, 重命名为 presto并通过 chmod +x将其设置为可执行文件。

  2. 启动命令:

# 参数server: coordinator的URI
# 参数catalog: 启用哪个数据源配置文件
# 参数schema: 
sudo ./presto --server localhost:8080 --catalog demo --schema default
  1. 执行查询:
select * from demo.blog_master_db.article union all select * from demo.blog_worker_db.article;
  1. 执行结果:可以看到1个SQL语句中将两个数据库blog_master_dbblog_worker_db的数据都查出来了。

Java JDBC连接

JDBC驱动介绍:允许用户在基于Java开发的应用或者在JVM上运行的非Java应用连接Presto。

环境:win10 + jdk 1.8 + maven 3.3.9 + idea 2019.2.4

  1. 使用idea创建1个空的maven工程。
  2. 在创建的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>
  1. 在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 {
        }

    }
}

  1. 执行结果:

Python客户端

目前有两个Python客户端可以连接presto:presto官方维护的presto-python-client,第三方维护的PyHive。PyHive的用户更多,而且可以结合SQLAlchemy使用。

presto-python-client

环境:win10 + python 3.6

  1. 安装:pip install presto-client
  2. 基于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)
  1. 查询结果:结果为python的list

PyHive

环境:win10 + python 3.6

  1. 安装:pip install pyhive

PyHive连接presto有两种方式:使用python DB-API,结合SQLAlchemy。

DB-API

  1. 与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())
  1. 查询结果:结果为python的list

SQLAlchemy

  1. 安装SQLAlchemy:conda install sqlalchemy
  2. 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)
  1. 查询结果:由于使用了pandas,查询结果为dataFrames

参考资料

  1. Presto Documents
  2. Presto Resources
  3. presto-python-client
  4. pyhive