Azure Databricks中通过ODBC连接SQL Server创建DataFrame及复制表求助
Azure Databricks连接SQL Server并生成结构化表完整实现
问题背景
在Azure Databricks环境中,需要连接ODBC SQL Server中的表,创建对应DataFrame并在Databricks内生成完全相同的表。目前编写的代码能获取数据,但无法得到结构化表,请求完整实现脚本。
原测试代码
pip install pyodbc import pyodbc server = 'XXXXXX-prod-db.database.chinacloudapi.cn' database = 'database-ods' username = 'os_reader' password = 'P@ssword' table = 'table_record' cnxn = pyodbc.connect( f'DRIVER={{ODBC Driver 17 for SQL Server}};' f'SERVER={server};' f'DATABASE={database};' f'UID={username};' f'PWD={password};' f'SELECT INTO={table}' ) cursor = cnxn.cursor() query = "SELECT * FROM " + table cursor.execute(query) rows = cursor.fetchall() print(rows)
完整实现方案
在Azure Databricks中,更推荐使用Spark原生JDBC方式连接SQL Server,直接生成结构化Spark DataFrame,后续可便捷写入Databricks内部表。以下是完整脚本:
步骤1:配置连接参数
# SQL Server核心连接参数 server = 'XXXXXX-prod-db.database.chinacloudapi.cn' database = 'database-ods' username = 'os_reader' password = 'P@ssword' target_table = 'table_record' # 适配中国区Azure的JDBC连接字符串 jdbc_url = f"jdbc:sqlserver://{server}:1433;databaseName={database};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.chinacloudapi.cn;loginTimeout=30;" conn_props = { "user": username, "password": password, "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver" }
步骤2:读取SQL Server表为结构化DataFrame
# 直接读取整张表到Spark DataFrame df = spark.read.jdbc(url=jdbc_url, table=target_table, properties=conn_props) # 验证表结构与数据 print("原表结构:") df.printSchema() print("前10条数据预览:") df.show(10)
步骤3:在Databricks内生成同结构表
选项1:写入Delta表(Databricks推荐格式)
# 写入到Databricks metastore的Delta表,支持ACID事务 df.write.format("delta").mode("overwrite").saveAsTable(f"default.{target_table}_copy") # 验证生成的表 spark.sql(f"SELECT * FROM default.{target_table}_copy LIMIT 10").show()
选项2:写入普通Parquet表
# 写入Parquet格式的托管表 df.write.mode("overwrite").saveAsTable(f"default.{target_table}_parquet")
关键说明
- 无需手动安装
pyodbc:Databricks环境已预装Spark JDBC依赖及SQL Server驱动,无需额外安装包。 - 结构化DataFrame优势:自动保留原表字段类型、Schema信息,可直接用于后续分析、ETL操作。
- 连接配置注意:中国区Azure SQL Server必须配置
encrypt=true和hostNameInCertificate,避免连接失败。
内容的提问来源于stack exchange,提问作者Emma
相关产品推荐
相关产品推荐

