Query serverless SQL pool from an Apache Spark Scala notebook

Published Apr 16 2021 04:21 AM 4,557 Views
Microsoft

Azure Synapse Analytics provides multiple query runtimes that you can use to query in-database or external data. You have the choice to use T-SQL queries using a serverless Synapse SQL pool or notebooks in Apache Spark for Synapse analytics to analyze your data.

You can also connect these runtimes and run the queries from Spark notebooks on a dedicated SQL pool.

In this post, you will see how to create Scala code in a Spark notebook that executes a T-SQL query on a serverless SQL pool.

 

Configuring connection to the serverless SQL pool endpoint

Azure Synapse Analytics enables you to run your queries on an external SQL query engine (Azure SQL, SQL Server, a dedicated SQL pool in Azure Synapse) using standard JDBC connection. With the Apache Spark runtime in Azure Synapse, you are also getting pre-installed driver that enables you to send a query to any T-SQL endpoint. This means that you can use this driver to run a query on a serverless SQL pool.

First, you need to initialize the connection with the following steps:

  • Define connection string to your remote T-SQL endpoint (serverless SQL pool in this case),
  • Specify properties (for example username/password)
  • Set the driver for connection.

The following Scala code contains the code that initializes connection to the serverless SQL pool endpoint:

 

 

 

// Define connection:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")

val hostname = "<WORKSPACE NAME>-ondemand.sql.azuresynapse.net"
val port = 1433
val database = "master" // If needed, change the database 
val jdbcUrl = s"jdbc:sqlserver://${hostname}:${port};database=${database}"

// Define connection properties:
import java.util.Properties

val props = new Properties()
props.put("user", "<sql login name>")
props.put("password", "<sql login password>")

// Assign driver to connection:
val driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
props.setProperty("Driver", driverClass)

 

 

This code should be placed in some cell in the notebook and you will be able to use this connection to query external T-SQL endpoints. In the following sections you will see how to read data from some SQL table or view or run ad-hoc query using this connection.

 

Reading content of SQL table

The serverless SQL pool in Azure Synapse enables you to create views and external tables over data stored in your Azure Data Lake Storage account or Azure CosmosDB analytical store. With the connection that is initialized in the previous step, you can easily read the content of the view or external table.

In the following simplified example, the Scala code will read data from the system view that exists on the serverless SQL pool endpoint:

 

 

val objects = spark.read.jdbc(jdbcUrl, "sys.objects", props).
objects.show(10)

 

 

If you create view or external table, you can easily read data from that object instead of system view.

You can easily specify what columns should be returned and some conditions:

 

 

val objects = spark.read.jdbc(jdbcUrl, "sys.objects", props).
                            select("object_id", "name", "type").
                            where("type <> 'S'")
objects.show(10)

 

 

 

Executing remote ad-hoc query

You can easily define T-SQL query that should be executed on remote serverless SQL pool endpoint and retrieve results. The Scala sample that can be added to the initial code is shown in the following listing:

 

 

val tsqlQuery =
"""
select top 10 *
from openrowset(
    bulk 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/ecdc_cases/latest/ecdc_cases.parquet',
    format = 'parquet') as rows
"""

val cases = spark.read.jdbc(jdbcUrl, s"(${tsqlQuery}) res", props)
cases.show(10)

 

 

The text of T-SQL query is defined the variable tsqlQuery. Spark notebook will execute this T-SQL query on the remote serverless Synapse SQL pool using spark.read.jdbc() function.

The results of this query are loaded into local data frame and displayed in the output.

 

Conclusion

Azure Synapse Analytics enables you to easily integrate analytic runtimes and run a query from the Apache Spark runtime on the Synapse SQL pool. Although Apache Spark has built-in functionalities that enable you to access data on Azure Storage, there some additional Synapse SQL functionalities that you can leverage in Spark jobs:

  • Accessing storage using SAS tokens or workspace managed identity. This way you can use serverless SQL pool to access Azure Data Lake storage protected with private endpoints or time limited keys.
  • Using custom language processing text rules. Synapse SQL contains text comparison and sorting rules for most of the world language. If you need to use case or accent insensitive searches or filter text using Japanese, France, German, or any other custom language rules, Synapse SQL provides native support for text processing.

The samples described in this article might help you to reuse functionalities that are available in serverless Synapse SQL pool to load data from Azure Data Lake storage or Azure Cosmos DB analytical store directly in your Spark Data Frames. Once you load your data, Apache Spark will enable you to analyze data sets using advanced data transformation and machine learning functionalities that exist in Spark libraries.

%3CLINGO-SUB%20id%3D%22lingo-sub-2250968%22%20slang%3D%22en-US%22%3EQuery%20serverless%20SQL%20pool%20from%20an%20Apache%20Spark%20Scala%20notebook%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2250968%22%20slang%3D%22en-US%22%3E%3CP%3EAzure%20Synapse%20Analytics%20provides%20multiple%20query%20runtimes%20that%20you%20can%20use%20to%20query%20in-database%20or%20external%20data.%20You%20have%20the%20choice%20to%20use%20T-SQL%20queries%20using%20a%20serverless%20Synapse%20SQL%20pool%20or%20notebooks%20in%20Apache%20Spark%20for%20Synapse%20analytics%20to%20analyze%20your%20data.%3C%2FP%3E%0A%3CP%3EYou%20can%20also%20connect%20these%20runtimes%20and%20run%20the%20queries%20from%20Spark%20notebooks%20on%20a%20dedicated%20SQL%20pool.%3C%2FP%3E%0A%3CP%3EIn%20this%20post%2C%20you%20will%20see%20how%20to%20create%20Scala%20code%20in%20a%20Spark%20notebook%20that%20executes%20a%20T-SQL%20query%20on%20a%20serverless%20SQL%20pool.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--495707104%22%20id%3D%22toc-hId--492818277%22%3EConfiguring%20connection%20to%20the%20serverless%20SQL%20pool%20endpoint%3C%2FH2%3E%0A%3CP%3EAzure%20Synapse%20Analytics%20enables%20you%20to%20run%20your%20queries%20on%20an%20external%20SQL%20query%20engine%20(Azure%20SQL%2C%20SQL%20Server%2C%20a%20dedicated%20SQL%20pool%20in%20Azure%20Synapse)%20using%20standard%20JDBC%20connection.%20With%20the%20Apache%20Spark%20runtime%20in%20Azure%20Synapse%2C%20you%20are%20also%20getting%20pre-installed%20driver%20that%20enables%20you%20to%20send%20a%20query%20to%20any%20T-SQL%20endpoint.%20This%20means%20that%20you%20can%20use%20this%20driver%20to%20run%20a%20query%20on%20a%20serverless%20SQL%20pool.%3C%2FP%3E%0A%3CP%3EFirst%2C%20you%20need%20to%20initialize%20the%20connection%20with%20the%20following%20steps%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EDefine%20connection%20string%20to%20your%20remote%20T-SQL%20endpoint%20(serverless%20SQL%20pool%20in%20this%20case)%2C%3C%2FLI%3E%0A%3CLI%3ESpecify%20properties%20(for%20example%20username%2Fpassword)%3C%2FLI%3E%0A%3CLI%3ESet%20the%20driver%20for%20connection.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EThe%20following%20Scala%20code%20contains%20the%20code%20that%20initializes%20connection%20to%20the%20serverless%20SQL%20pool%20endpoint%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-java%22%3E%3CCODE%3E%2F%2F%20Define%20connection%3A%0AClass.forName(%22com.microsoft.sqlserver.jdbc.SQLServerDriver%22)%0A%0Aval%20hostname%20%3D%20%22%3CWORKSPACE%20name%3D%22%22%3E-ondemand.sql.azuresynapse.net%22%0Aval%20port%20%3D%201433%0Aval%20database%20%3D%20%22master%22%20%2F%2F%20If%20needed%2C%20change%20the%20database%20%0Aval%20jdbcUrl%20%3D%20s%22jdbc%3Asqlserver%3A%2F%2F%24%7Bhostname%7D%3A%24%7Bport%7D%3Bdatabase%3D%24%7Bdatabase%7D%22%0A%0A%2F%2F%20Define%20connection%20properties%3A%0Aimport%20java.util.Properties%0A%0Aval%20props%20%3D%20new%20Properties()%0Aprops.put(%22user%22%2C%20%22%3CSQL%20login%3D%22%22%20name%3D%22%22%3E%22)%0Aprops.put(%22password%22%2C%20%22%3CSQL%20login%3D%22%22%20password%3D%22%22%3E%22)%0A%0A%2F%2F%20Assign%20driver%20to%20connection%3A%0Aval%20driverClass%20%3D%20%22com.microsoft.sqlserver.jdbc.SQLServerDriver%22%0Aprops.setProperty(%22Driver%22%2C%20driverClass)%3C%2FSQL%3E%3C%2FSQL%3E%3C%2FWORKSPACE%3E%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThis%20code%20should%20be%20placed%20in%20some%20cell%20in%20the%20notebook%20and%20you%20will%20be%20able%20to%20use%20this%20connection%20to%20query%20external%20T-SQL%20endpoints.%20In%20the%20following%20sections%20you%20will%20see%20how%20to%20read%20data%20from%20some%20SQL%20table%20or%20view%20or%20run%20ad-hoc%20query%20using%20this%20connection.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-1991805729%22%20id%3D%22toc-hId-1994694556%22%3EReading%20content%20of%20SQL%20table%3C%2FH2%3E%0A%3CP%3EThe%20serverless%20SQL%20pool%20in%20Azure%20Synapse%20enables%20you%20to%20create%20views%20and%20external%20tables%20over%20data%20stored%20in%20your%20Azure%20Data%20Lake%20Storage%20account%20or%20Azure%20CosmosDB%20analytical%20store.%20With%20the%20connection%20that%20is%20initialized%20in%20the%20previous%20step%2C%20you%20can%20easily%20read%20the%20content%20of%20the%20view%20or%20external%20table.%3C%2FP%3E%0A%3CP%3EIn%20the%20following%20simplified%20example%2C%20the%20Scala%20code%20will%20read%20data%20from%20the%20system%20view%20that%20exists%20on%20the%20serverless%20SQL%20pool%20endpoint%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-java%22%3E%3CCODE%3Eval%20objects%20%3D%20spark.read.jdbc(jdbcUrl%2C%20%22sys.objects%22%2C%20props).%0Aobjects.show(10)%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIf%20you%20create%20view%20or%20external%20table%2C%20you%20can%20easily%20read%20data%20from%20that%20object%20instead%20of%20system%20view.%3C%2FP%3E%0A%3CP%3EYou%20can%20easily%20specify%20what%20columns%20should%20be%20returned%20and%20some%20conditions%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-java%22%3E%3CCODE%3Eval%20objects%20%3D%20spark.read.jdbc(jdbcUrl%2C%20%22sys.objects%22%2C%20props).%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20select(%22object_id%22%2C%20%22name%22%2C%20%22type%22).%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20where(%22type%20%26lt%3B%26gt%3B%20'S'%22)%0Aobjects.show(10)%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-184351266%22%20id%3D%22toc-hId-187240093%22%3EExecuting%20remote%20ad-hoc%20query%3C%2FH2%3E%0A%3CP%3EYou%20can%20easily%20define%20T-SQL%20query%20that%20should%20be%20executed%20on%20remote%20serverless%20SQL%20pool%20endpoint%20and%20retrieve%20results.%20The%20Scala%20sample%20that%20can%20be%20added%20to%20the%20initial%20code%20is%20shown%20in%20the%20following%20listing%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-applescript%22%3E%3CCODE%3Eval%20tsqlQuery%20%3D%0A%22%22%22%0Aselect%20top%2010%20*%0Afrom%20openrowset(%0A%20%20%20%20bulk%20'https%3A%2F%2Fpandemicdatalake.blob.core.windows.net%2Fpublic%2Fcurated%2Fcovid-19%2Fecdc_cases%2Flatest%2Fecdc_cases.parquet'%2C%0A%20%20%20%20format%20%3D%20'parquet')%20as%20rows%0A%22%22%22%0A%0Aval%20cases%20%3D%20spark.read.jdbc(jdbcUrl%2C%20s%22(%24%7BtsqlQuery%7D)%20res%22%2C%20props)%0Acases.show(10)%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20text%20of%20T-SQL%20query%20is%20defined%20the%20variable%20%3CSTRONG%3EtsqlQuery%3C%2FSTRONG%3E.%20Spark%20notebook%20will%20execute%20this%20T-SQL%20query%20on%20the%20remote%20serverless%20Synapse%20SQL%20pool%20using%20%3CSTRONG%3Espark.read.jdbc()%3C%2FSTRONG%3E%20function.%3C%2FP%3E%0A%3CP%3EThe%20results%20of%20this%20query%20are%20loaded%20into%20local%20data%20frame%20and%20displayed%20in%20the%20output.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--1623103197%22%20id%3D%22toc-hId--1620214370%22%3EConclusion%3C%2FH2%3E%0A%3CP%3EAzure%20Synapse%20Analytics%20enables%20you%20to%20easily%20integrate%20analytic%20runtimes%20and%20run%20a%20query%20from%20the%20Apache%20Spark%20runtime%20on%20the%20Synapse%20SQL%20pool.%20Although%20Apache%20Spark%20has%20built-in%20functionalities%20that%20enable%20you%20to%20access%20data%20on%20Azure%20Storage%2C%20there%20some%20additional%20Synapse%20SQL%20functionalities%20that%20you%20can%20leverage%20in%20Spark%20jobs%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EAccessing%20storage%20using%20SAS%20tokens%20or%20workspace%20managed%20identity.%20This%20way%20you%20can%20use%20serverless%20SQL%20pool%20to%20access%20Azure%20Data%20Lake%20storage%20protected%20with%20private%20endpoints%20or%20time%20limited%20keys.%3C%2FLI%3E%0A%3CLI%3EUsing%20custom%20language%20processing%20text%20rules.%20Synapse%20SQL%20contains%20text%20comparison%20and%20sorting%20rules%20for%20most%20of%20the%20world%20language.%20If%20you%20need%20to%20use%20case%20or%20accent%20insensitive%20searches%20or%20filter%20text%20using%20Japanese%2C%20France%2C%20German%2C%20or%20any%20other%20custom%20language%20rules%2C%20Synapse%20SQL%20provides%20native%20support%20for%20text%20processing.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EThe%20samples%20described%20in%20this%20article%20might%20help%20you%20to%20reuse%20functionalities%20that%20are%20available%20in%20serverless%20Synapse%20SQL%20pool%20to%20load%20data%20from%20Azure%20Data%20Lake%20storage%20or%20Azure%20Cosmos%20DB%20analytical%20store%20directly%20in%20your%20Spark%20Data%20Frames.%20Once%20you%20load%20your%20data%2C%20Apache%20Spark%20will%20enable%20you%20to%20analyze%20data%20sets%20using%20advanced%20data%20transformation%20and%20machine%20learning%20functionalities%20that%20exist%20in%20Spark%20libraries.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-2250968%22%20slang%3D%22en-US%22%3E%3CP%3EApache%20Spark%20notebooks%20in%20Azure%20Synapse%20Analytics%20workspace%20can%20execute%20T-SQL%20queries%20on%20a%20serverless%20Synapse%20SQL%20pool.%20This%20way%20you%20can%20leverage%20load%20data%20from%20some%20SQL%20table%20or%20view%26nbsp%3B%20into%20your%20Apache%20Spark%20data%20frames%20apply%20some%20advanced%20data%20processing.%20In%20this%20article%20you%20will%20learn%20how%20to%20call%20SQL%20code%20form%20spark%20notebook.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Teaser%20card%20-%20SQL.PNG%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F310651iD80064403547DA40%2Fimage-size%2Fmedium%3Fv%3Dv2%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22Teaser%20card%20-%20SQL.PNG%22%20alt%3D%22Teaser%20card%20-%20SQL.PNG%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%E2%80%83%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2250968%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%20Databricks%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESynapse%20Spark%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESynapse%20SQL%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Co-Authors
Version history
Last update:
‎Sep 15 2021 12:04 PM
Updated by: