SQLFlow: A Bridge between SQL and Machine Learning

Industrial AI systems are mostly end-to-end machine learning (ML) workflows. A typical recommendation or business intelligence system includes many online micro-services and offline jobs. We describe SQLFlow for developing such workflows efficiently in SQL. SQL enables developers to write short programs focusing on the purpose (what) and ignoring the procedure (how). Previous database systems extended their SQL dialect to support ML. SQLFlow (https://sqlflow.org/sqlflow ) takes another strategy to work as a bridge over various database systems, including MySQL, Apache Hive, and Alibaba MaxCompute, and ML engines like TensorFlow, XGBoost, and scikit-learn. We extended SQL syntax carefully to make the extension working with various SQL dialects. We implement the extension by inventing a collaborative parsing algorithm. SQLFlow is efficient and expressive to a wide variety of ML techniques – supervised and unsupervised learning; deep networks and tree models; visual model explanation in addition to training and prediction; data processing and feature extraction in addition to ML. SQLFlow compiles a SQL program into a Kubernetes-native workflow for fault-tolerable execution and on-cloud deployment. Current industrial users include Ant Financial, DiDi, and Alibaba Group.



There are no comments yet.


page 1


sql4ml A declarative end-to-end workflow for machine learning

We present sql4ml, a system for expressing supervised machine learning (...

Synthesis of SQL Queries from South African Local Language Narrations

English remains the language of choice for database courses and widely u...

Snel: SQL Native Execution for LLVM

Snel is a relational database engine featuring Just-In-Time (JIT) compil...

In-Machine-Learning Database: Reimagining Deep Learning with Old-School SQL

In-database machine learning has been very popular, almost being a clich...

Efficient and Accurate In-Database Machine Learning with SQL Code Generation in Python

Following an analysis of the advantages of SQL-based Machine Learning (M...

LIKE Patterns and Complexity

We investigate the expressive power and complexity questions for the LIK...

Extending Relational Query Processing with ML Inference

The broadening adoption of machine learning in the enterprise is increas...
This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1. Introduction

Figure 1. SQLFlow with Jupyter Notebook as the GUI.

SQLFlow with Jupyter

Most industrial AI systems are end-to-end machine learning workflows of multiple steps. Typical workflows include search engines, recommendation systems for e-commerce, and business analysis platforms like Salesforce. A workflow usually starts with a Web server that creates the UI, followed by log collectors like fluientd, log streams aggregators like Kafka, database systems like Apache Hive, and ML systems built on top of TensorFlow (Abadi and et al, 2016)

, PyTorch 

(Paszke et al., 2017), XGBoost (Chen and Guestrin, 2016), or scikit-learn (Pedregosa et al., 2011). Most workflows are cyclic because the trained models help the Web server to answer more user questions via an online serving system or offline scoring system. Each of such a workflow might need tens or hundreds of engineers to build and continuously improve.

A recent trend to simplify the development of end-to-end ML workflows, with the commonly used components getting modulized, is to program and deploy the workflow as a whole using expressive languages like Python. Examples include Amazon SageMaker (Joshi, 2020), Netflix Metaflow (1), and BlazingSQL (Ocsa, 2019).

We propose SQLFlow to program in SQL other than Python. SQL is unique as it allows programmers to focus on their purposes while ignoring the procedure of achieving that purpose, thus improves the development efficiency significantly. Figure 1 shows how to train an XGBoost model, make a prediction, and visually explain the model by calling SHAP (Lundberg and Lee, 2017). The SQLFlow syntax extension used in this SQL program takes care of data pre-processing and extracts features automatically.

Some database systems extend their SQL dialects to support ML. For example, Google BigQuery (Tigani and Naidu, 2014), a database system running on Google Cloud, adds the CREATE MODEL statement for training ML models. Other examples include Microsoft SQL Server Machine Learning Services (13), Azure SQL Database (Copeland, 2015), Amazon Athena (3), IBM DB2 (Tian et al., 2019), Apache Madlib (Feng et al., 2012), and MemSQL (Shamgunov, 2020). However, these approaches have some drawbacks.

  • They lock end-to-end ML users to specific database systems. Switching to another database system requires rewriting of all ML solutions.

  • Most of the above systems and their extensions are not open-source, thus prohibits community contributions of ML features.

  • These solutions are based on existing database computing infrastructures, and cannot use the fault-tolerance and extensibility of general cluster computing technologies like Kubernetes.

SQLFlow takes a different strategy. It is open-sourced and works like a bridge connecting various database systems and ML engines. Since open-sourced in May 2019, the community added support to MySQL, Apache Hive, Alibaba MaxCompute, TensorFlow, XGBoost, scikit-learn, and SHAP. The list is growing. To make the ML syntax extension to work with various SQL dialects, we carefully designed the extension and invented a collaborative parsing algorithm, which calls parsers of SQL dialects and that of the syntax extension.

Instead of running ML workloads on database infrastructure, SQLFlow compiles SQL programs into workflows for deployment and execution on Kubernetes, which is overwhelming public clouds and on-premise clusters. Workflow execution engines, like Argo222https://argoproj.github.io and Tekton333https://github.com/tektoncd/pipeline, run on Kubernetes and provide fault-tolerance and scalability. SQLFlow-generated workflows access the database systems and ML engines, which also run on Kubernetes. The compilation algorithm automatically generates workflow steps like data cleanup and feature extraction to fill the gap between raw data and ML.

In the ecosystem of end-to-end ML, there are three roles:

  • End-to-end ML users call ML models from SQL.

  • ML researchers define models in Python and abstraction APIs like Keras.

  • Tool developers create ML engines and database systems in mostly C++ and Go.

ML researchers need to write workflows to verify and test model definitions. When doing so, they prefer using their well-used tool Python. However, Argo and Tekton accept YAML files, which are lengthy and error-prone to write. To flourishing the community, SQLFlow provides Couler, a Python library for describing workflows. Tool developers can contribute Couler functions to encapsulate their tools, for example, couler.train_xgboost_model and couler.run_mysql_query. ML researchers can call these functions to build up their workflows. SQLFlow translates SQL programs in Couler programs to ease of debugging. Couler then translates Python programs into YAML files.

The open architecture of SQLFlow poses some restrictions. For example, we don’t yet have a plan to support transactions shortly. Users can use the transaction mechanism provided by the database systems in their SQL programs, as the generated workflow submits ”normal SQL statements” to the database system for execution. However, SQL statements with SQLFlow syntax extensions can not be in part of the transactions.

2. Syntax Extension

Some prior work adds user-defined functions (UDFs) to a database system to support ML. For SQLFlow, however, it is intractable to implement the UDFs for all combinations of the supported database and ML systems. Some other works introduce new statements. For example, Google BigQuery has the CREATE MODEL statement. We noticed that many data analysts have SELECT statements for data cleaning, data transformation, and feature extraction. The next thing in their mind is naturally ML. It is intuitive to append a clause for the purpose. SQLFlow introduces the following clause extensions.

    SELECT ... TO TRAIN model_definition
                    WITH parameters
                    COLUMN features LABEL target
                    INTO model_name;
    SELECT ... TO PREDICT field USING model_name;
    SELECT ... TO EXPLAIN model_name WITH parameters;

The TRAIN clause trains a model using the result from the SELECT statement, where model_definition names a Python class that defines a model. For example, DNNRegressor, or prefixed with the package name, dnn.Regressor, and even Docker image name, sqlflow/models.dnn.Regressor. The identifier model_name names an output folder for saving the trained model parameters. It can be a URL pointing to external storage like Amazon S3. Users can specify ML parameters using the WITH clause. For example, WITH learning_rate=0.01, hidden_units=[10, 100, 15]. We are working on automatic parameters tuning using Katib444https://github.com/kubeflow/katib. The COLUMN and LABEL clauses specify the input and output of models. LABEL is not required when training unsupervised models.

The PREDICT clause makes a prediction using a trained model. The EXPLAIN clause visually explains a model.

The word TO before TRAIN, PREDICT, and EXPLAIN is necessary for disambiguation. In some SQL dialects, for example, MySQL, the SELECT statement could have aliases. Users can write SELECT * FROM t1, t2, t3 TRAIN … where TRAIN is an alias of table t3. As a reserved keyword in the SQL language specification, various dialects don’t accept TO as table or alias name.

3. Collaborative Parsing

The collaborative parsing algorithm allows SQLFlow to understand “normal statements” of SQL dialects, and those SELECT statements followed by SQLFlow extension clauses. This parsing algorithm can use any open-source parser, like the MySQL/TiDB, HiveQL, and Calcite parser, and proprietary parser under grants when we integrate with non-open-source systems. This parsing algorithm also calls the SQLFlow extension parser written in goyacc and understanding only the TO TRAIN, PREDICT, and EXPLAIN clauses. As shown below, the collaborative parser repeatedly calls the dialect parser via parseDialect and the SQLFlow extension parser via parseExtension.

Input: A SQL program with optional SQLFlow extensions
Output: Parsed statement list and optionally an error
lst [] while True do
       stmts, stop_at, err parseDialect(program) if err nil then
             return [], err
       lst append(lst, stmts) if stop_at the end of program then
             return lst, nil
       program program[stop_at:] ext, stop_at, err parseExtension(program) if err nil then
             return [], err
       lst appendExtension(lst, ext) if stop_at the end of program then
             return lst, nil
       program program[stop_at:]
end while

The function parseDialect calls the dialect parser up to twice. The first call would fail if there is an SQLFlow extension clause in the program and stop at the beginning of the clause. In this case, parseDialect makes a second call to parse the part of the SQL program before the error position, which is before the extension clause. If there are no syntax errors in that part, the second call succeeds. This algorithm relies on the convention that the dialect parsers report error position, which is true because parsers are supposed to report errors position. They do this in different ways; for example, the MySQL/TiDB parser returns strings, but HiveQL and Calcite parser throw exceptions. We have a thin layer of abstraction to shield these minor differences.

4. Compile SQL to Workflow

SQLFlow can run as a gRPC server or a command-line tool. In either way, it compiles a SQL program into a workflow. We used to represent a workflow by a Python program, which, however, is not fault-tolerable. In industrial deployments, like on Kubernetes clusters, the SQLFlow service runs as a group of replicated processes, and Kubernetes might preempt some processes when scheduling. If the workflow runs as a Python program, they are subject to preemption. As a solution, we changed SQLFlow to generate workflows in the form of YAML files for the execution by fault-tolerable engines like Argo and Tekton.

4.1. Python API of Workflow

The Argo/Tekton YAML files are hard to read and debug. So we wrote a Python library Couler to represent workflows as Python source code. The following 6-line Python program runs and prints a 46-line YAML file representing an equivalent workflow task of two steps. The YAML file are for execution by Argo/Tekton. In practice, we have Couler functions corresponding to ML and database systems like train_xgboost_model and run_mysql_query.

    def echo_hello_world(hello, world="El mundo"):
        couler.step(cmd=["echo"], args=[hello])
        couler.step(cmd=["echo"], args=[world])

4.2. Two-Tier Compilation

SQLFlow features a two-tier compilation architecture. The top one translates a SQL program into a YAML, where each SQL statement is a step. Argo and Tekton run each step as a container, inside which, SQLFlow translates the SQL statement into a Python program and runs it. If the statement is a normal one, the generated Python program submits it literally to the database system for execution; or, if it is a SELECT statement with SQLFlow extension, the Python program retrieves data, extracts features, and launches the ML task.

The two-tier compilation is necessary because SQLFlow needs to do feature extraction, an essential part of end-to-end machine learning, at run-time, after the execution of previous SQL statements and the schema of the input data table is known. The second tier compilation happens at the run-time of the first tier.

5. Demo Overview

Episode Database system Database deployment ML system Model explanation Learning paradigm UI
One. MySQL local XGBoost SHAP Supervised Jupyter
Two. Apache Hive Docker TensorFlow SHAP Supervised Jupyter
Three. Alibaba MaxCompute Cloud scikit-learn metaplot Unsupervised Jupyter
Four. MySQL Kubernetes XGBoost a text-backend for SHAP Supervised Terminal
Table 1. Episodes in the Demo

The objectives of this demo are to show SIGMOD attendees: (1) the superior efficiency of end-to-end machine learning experience provided by an open architecture that connects various database and ML systems, (2) the expressiveness of SQLFlow syntax extension on both supervised and unsupervised learning, and (3) the versatility to integrate with GUI systems and to work alone as command-line compiler toolchain.

We plan to run SQLFlow as a local service so that users can interact with it via Jupyter Notebook or from the command-line. We plan to preload datasets to MySQL and Hive running locally and to MaxCompute running on the public cloud; users can access them from SQLFlow. We provide a supplementary video with this paper showing four episodes; each is a typical use case. As shown in Table 1

, these examples cover four datasets, various combinations of database and ML systems, tree models and deep learning models, supervised and unsupervised learning. They also cover visual model explanations in the GUI and a text-based terminal. The audience can freely change example SQL programs used in the episodes and invent their own. They are free to invent new combinations out of Table 

1, like unsupervised learning with MySQL and XGBoost models with Hive.

Episode One.

This episode shows SQLFlow works with MySQL and XGBoost on supervised learning of tree models. It also shows the visual model explanation in Jupyter Notebook by calling SHAP. The dataset is Boston Housing

555https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html. This episode includes the following steps. (1) Dataset examination by SELECT few rows to display in the Jupyter Notebook. Demo audience can change and add new SQL statements freely to, say, select a subset of the dataset, or split the dataset into training and test data. (2) We train an XGBoost model using the SELECT … TO TRAIN syntax extension. The audience can train any other models in the model zoo. (3) Using the SELECT … TO PREDICT syntax extension, we make a prediction using the trained model. And (4) Using the SELECT … TO EXPLAIN extension, we explain the model visually as an image showing in Jupyter Notebook. The audience can change visual explainer and get other types of visualizations.

Episode Two.

This episode shows SQLFlow works with Apache Hive and TensorFlow using the Iris Dataset666https://en.wikipedia.org/wiki/Iris_flower_data_set. This episode follows the same steps as Episode One but focusing on deep learning models other than tree models.

Episode Three.

Differing from the previous two, this episode is about unsupervised learning. It uses Alibaba MaxCompute and scikit-learn. The dataset is the Electric Power Consumption777https://www.kaggle.com/uciml/electric-power-consumption-data-set. SHAP doesn’t support explaining an unsupervised model, so we created our own tool with metaplot. Episode Three consists of the same steps as the previous episodes.

Episode Four.

The episode shows how to use SQLFlow as a command line tool that compiles a SQL program to workflow, as explained in Section 4. This episode includes the following steps. (1) In the terminal, we type a command to convert the SQL program used in episode one into a Couler program. (2) Using the command-line tool couler, we convert the Couler program into a YAML file. (3) Using the workflow engine Argo’s client tool, we submit the YAML for execution on a Kubernetes cluster. The audience is free to compare the SQL, Couler, and YAML files; they would notice that the SQL program has a few lines of code, the Couler program is longer than the SQL program, and the YAML file is very lengthy. In the dashboard of Argo in a Web browser, the audience is free to explore the visualized steps and their running progress. They are can also type Argo commands to monitor the progress and logs using command-line tools in the terminal. In the terminal, the audience can see the visual model explanation in the form of ASCII-art generated by a text-based backend we invented to work with SHAP. From these steps, the audience might feel that sqlflow works like GCC as a compiler and couler works like LD as a linker as it generates an executable (YAML) file.


  • [1] (2020)(Website) External Links: Link Cited by: §1.
  • M. Abadi and et al (2016) TensorFlow: a system for large-scale machine learning. In 12th USENIX Symposium on Operating Systems Design and Implementation (OSDI 16), Savannah, GA, pp. 265–283. External Links: ISBN 978-1-931971-33-1 Cited by: §1.
  • [3] (2020)(Website) External Links: Link Cited by: §1.
  • T. Chen and C. Guestrin (2016) Xgboost: a scalable tree boosting system. In Proceedings of the 22nd acm sigkdd international conference on knowledge discovery and data mining, pp. 785–794. Cited by: §1.
  • M. Copeland (2015) Microsoft azure: planning, deploying, and managing your data center in the cloud. Apress. Cited by: §1.
  • X. Feng, A. Kumar, B. Recht, and C. Ré (2012) Towards a unified architecture for in-rdbms analytics. In Proceedings of the 2012 ACM SIGMOD International Conference on Management of Data, pp. 325–336. Cited by: §1.
  • A. V. Joshi (2020) Amazon’s machine learning toolkit: sagemaker. In

    Machine Learning and Artificial Intelligence

    pp. 233–243. External Links: ISBN 978-3-030-26622-6, Document, Link Cited by: §1.
  • S. M. Lundberg and S. Lee (2017) A unified approach to interpreting model predictions. In Advances in Neural Information Processing Systems 30, I. Guyon, U. V. Luxburg, S. Bengio, H. Wallach, R. Fergus, S. Vishwanathan, and R. Garnett (Eds.), pp. 4765–4774. Cited by: §1.
  • A. Ocsa (2019)

    SQL for GPU Data Frames in RAPIDS Accelerating end-to-end data science workflows using GPUs

    Note: PosterLatinX in AI Research at ICML 2019 Cited by: §1.
  • A. Paszke, S. Gross, S. Chintala, G. Chanan, E. Yang, Z. DeVito, Z. Lin, A. Desmaison, L. Antiga, and A. Lerer (2017) Automatic differentiation in pytorch. Cited by: §1.
  • F. Pedregosa, G. Varoquaux, A. Gramfort, V. Michel, B. Thirion, O. Grisel, M. Blondel, P. Prettenhofer, R. Weiss, V. Dubourg, J. Vanderplas, A. Passos, D. Cournapeau, M. Brucher, M. Perrot, and E. Duchesnay (2011) Scikit-learn: Machine Learning in Python . Journal of Machine Learning Research 12, pp. 2825–2830. Cited by: §1.
  • N. Shamgunov (2020) External Links: Link Cited by: §1.
  • [13] (2020)(Website) External Links: Link Cited by: §1.
  • Y. Tian, W. Sun, S. J. Tong, E. L. Xu, M. H. Pirahesh, and W. Zhao (2019) Synergistic graph and sql analytics inside ibm db2. Proceedings of the VLDB Endowment 12 (12), pp. 1782–1785. Cited by: §1.
  • J. Tigani and S. Naidu (2014) Google bigquery analytics. John Wiley & Sons. Cited by: §1.