我在使用 Synapse Analytics 时遇到问题。要求是使用 python3 脚本读取表数据。为此,我们在 Synapse 分析上使用无服务器 SQL 池,并使用 ADLSGen2 中的 parquet 文件创建外部表(在设置链接服务之后)。我能够查询 Synapse Analytics > Develope > SQL 脚本中的表,但是当我尝试使用脚本访问它时,出现以下错误:
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][SQL Server 的 ODBC 驱动程序 18][SQL Server] 外部表 'Employee_table' 无法访问,因为位置不存在或已被另一个进程使用。 (16562) (SQLExecDirectW)")
我正在使用的Python脚本:
import pyodbc
import pandas as pd
import sys
import logging
import traceback
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def main():
try:
# Set up connection to Synapse
server = 'serverless-synapse-analytics-ondemand.sql.azuresynapse.net' #serverless endpoint
database = 'synapse_analytics'
username = 'liveuser'
password = 'StrongPassword!@#0'
driver= '{ODBC Driver 18 for SQL Server}'
conn_str = 'DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password
conn = pyodbc.connect(conn_str)
cursor = conn.cursor()
#print success message if connect is successful
if conn:
print('Connection established')
# Execute a query and print the top 100 result rows
sql = """select top 10 * from SAM_table"""
cursor.execute(sql)
rows = cursor.fetchall()
print(rows.head(3))
# Close the connection
conn.close()
except Exception as e:
logger.error(f'Error: {e}')
logger.error(f'Trace: {traceback.format_exc()}')
if __name__ == '__main__':
main()
使用上面的代码,我能够与 synapse 连接(获取成功消息:已建立连接),但是当我尝试执行 SQL 查询时,出现错误。
我在这里缺少什么?或者如何修改代码,以便我可以读取数据?
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]External table 'Employee_table' is not accessible because location does not exist or it is used by another process. (16562) (SQLExecDirectW)")
您尝试连接到 SQL 数据库的用户(即
liveuser
)无权从附加到无服务器 SQL 池的 ADLS Gen2 帐户读取数据。这可能是从 Serverless SQL 池读取表数据时出现上述错误的原因。您可以按照以下过程在 Synapse 笔记本中使用 Python 脚本从无服务器 SQL 池读取数据:
使用无服务器 SQL 池端点创建 Azure SQL 数据库链接服务,使用系统分配的身份验证,如下所示:
发布链接服务,并使用以下代码连接到 Synapse 笔记本中的无服务器 SQL 池:
server = '<serverName>-ondemand.sql.azuresynapse.net'
Port = 1433
Database = "db"
jdbcUrl = f"jdbc:sqlserver://{server}:{Port};databaseName={Database};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30"
token=TokenLibrary.getConnectionString("<linkedServiceName>")
query = "(SELECT * FROM <tableName>) as tb"
conn_Prop = {
"driver" : "com.microsoft.sqlserver.jdbc.SQLServerDriver",
"accessToken" : token
}
df = spark.read.jdbc(url=jdbcUrl, table=query, properties=conn_Prop)
display(df)
连接成功,查询表如下: