核心概念
要在 Python 中与 SQL Server 交互,你需要一个“桥梁”,这个桥梁就是 数据库驱动程序,最常用和推荐的驱动是 pyodbc,它是一个开源的 Python 模块,允许 Python 程序通过 ODBC (Open Database Connectivity) 连接到几乎所有的数据库,包括 SQL Server。

第一步:环境准备
在写代码之前,请确保你已经准备好了以下环境:
安装 Python 驱动
打开你的终端或命令提示符,使用 pip 安装 pyodbc。
pip install pyodbc
安装 ODBC 驱动 (关键步骤!)
pyodbc 本身只是一个接口,它需要调用系统底层的 ODBC 驱动来与 SQL Server 通信,你必须在你的操作系统(Windows, macOS, Linux)上安装相应的 ODBC 驱动。
-
Windows:
(图片来源网络,侵删)- 推荐安装: Microsoft ODBC Driver 18 for SQL Server
- 这个驱动是最新、性能最好的版本,安装时,在安装程序界面勾选 "ODBC Driver 18 for SQL Server" 即可。
-
macOS:
- 可以使用 Homebrew 安装:
brew update brew install microsoft/mssql-release/msodbcsql18
- 可以使用 Homebrew 安装:
-
Linux (如 Ubuntu):
- 按照官方文档进行安装,通常需要添加 Microsoft 的软件源并安装
msodbcsql18包,具体步骤可以参考 Microsoft 官方文档。
- 按照官方文档进行安装,通常需要添加 Microsoft 的软件源并安装
准备 SQL Server 数据库和表
你需要一个可以连接的 SQL Server 实例,并且有一个数据库和一张表来存储数据。
我们创建一个简单的 Employees 表:
-- 在 SQL Server Management Studio (SSMS) 或其他工具中执行
USE YourDatabaseName; -- 替换为你的数据库名
GO
CREATE TABLE Employees (
ID INT PRIMARY KEY IDENTITY(1,1),
FirstName NVARCHAR(50) NOT NULL,
LastName NVARCHAR(50) NOT NULL,
Department NVARCHAR(50),
HireDate DATE
);
GO
第二步:Python 连接与存储代码
我们将分几种常见场景来演示如何存储数据。
存储单条记录(使用参数化查询,最安全)
这是最基本也是最推荐的方式,可以有效防止 SQL 注入攻击。
import pyodbc
# --- 1. 定义连接信息 ---
# 你需要根据你的环境修改这些信息
server = 'your_server_name' # 'localhost', 'SERVER\\SQLEXPRESS'
database = 'YourDatabaseName' # 你的数据库名
username = 'your_username' # 你的 SQL Server 用户名
password = 'your_password' # 你的密码
# 注意:如果你的 SQL Server 配置了 Windows 身份验证,可以这样连接:
# trusted_connection = 'yes'
# connection_string = f'DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={server};DATABASE={database};Trusted_Connection={trusted_connection}'
# --- 2. 创建连接字符串 ---
# 驱动名称请确保与你的系统安装的驱动一致,"ODBC Driver 17 for SQL Server"
# 'TrustServerCertificate=yes' 可以在本地开发时简化 SSL 证书验证,生产环境请谨慎使用
connection_string = f'DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password};TrustServerCertificate=yes'
try:
# --- 3. 建立数据库连接 ---
conn = pyodbc.connect(connection_string)
print("成功连接到 SQL Server!")
# --- 4. 创建一个游标对象 ---
# 游标用于执行 SQL 语句
cursor = conn.cursor()
# --- 5. 定义要执行的 SQL 插入语句 (使用参数化查询) ---
# 使用 ? 作为占位符,这是 pyodbc 的标准做法
sql_insert_query = "INSERT INTO Employees (FirstName, LastName, Department, HireDate) VALUES (?, ?, ?, ?)"
# --- 6. 定义要插入的数据 ---
employee_data = ('John', 'Doe', 'Engineering', '2025-01-15')
# --- 7. 执行 SQL 语句 ---
cursor.execute(sql_insert_query, employee_data)
# --- 8. 提交事务 ---
# 如果没有 commit,更改不会被永久保存到数据库中
conn.commit()
print(f"成功插入 1 条记录,ID: {cursor.rowcount}")
except pyodbc.Error as e:
print(f"数据库操作失败: {e}")
# 如果发生错误,回滚事务
if conn:
conn.rollback()
finally:
# --- 9. 关闭连接 ---
# 确保连接被关闭,释放资源
if 'conn' in locals() and conn:
cursor.close()
conn.close()
print("数据库连接已关闭。")
批量插入多条记录(最高效)
当需要插入大量数据时,逐条执行效率很低。pyodbc 的 executemany 方法可以极大地提高性能。
import pyodbc
# 连接信息同上
server = 'your_server_name'
database = 'YourDatabaseName'
username = 'your_username'
password = 'your_password'
connection_string = f'DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password};TrustServerCertificate=yes'
try:
conn = pyodbc.connect(connection_string)
cursor = conn.cursor()
# 定义 SQL 插入语句
sql_insert_query = "INSERT INTO Employees (FirstName, LastName, Department, HireDate) VALUES (?, ?, ?, ?)"
# 定义一个包含多条记录的列表
employees_to_insert = [
('Jane', 'Smith', 'Marketing', '2025-05-20'),
('Peter', 'Jones', 'Sales', '2025-03-10'),
('Mary', 'Williams', 'HR', '2025-11-01'),
('David', 'Brown', 'Engineering', '2025-02-28')
]
# 使用 executemany 进行批量插入
cursor.executemany(sql_insert_query, employees_to_insert)
# 提交事务
conn.commit()
print(f"成功批量插入 {cursor.rowcount} 条记录。")
except pyodbc.Error as e:
print(f"数据库操作失败: {e}")
if conn:
conn.rollback()
finally:
if 'conn' in locals() and conn:
cursor.close()
conn.close()
print("数据库连接已关闭。")
从 Pandas DataFrame 存储数据(数据科学常用)
如果你正在使用 pandas 进行数据分析,可以直接将 DataFrame 存入 SQL Server。
确保你安装了 pandas:
pip install pandas
import pyodbc
import pandas as pd
# 连接信息同上
server = 'your_server_name'
database = 'YourDatabaseName'
username = 'your_username'
password = 'your_password'
connection_string = f'DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password};TrustServerCertificate=yes'
try:
# --- 1. 创建一个示例 DataFrame ---
data = {
'FirstName': ['Alice', 'Bob', 'Charlie'],
'LastName': ['Wonder', 'Builder', 'Delta'],
'Department': ['R&D', 'Operations', 'R&D'],
'HireDate': pd.to_datetime(['2025-01-01', '2025-02-02', '2025-03-03'])
}
df = pd.DataFrame(data)
# --- 2. 建立连接 ---
conn = pyodbc.connect(connection_string)
# --- 3. 使用 to_sql 方法将 DataFrame 写入数据库 ---
# if_exists='append': 如果表已存在,则追加数据
# index=False: 不将 DataFrame 的索引列写入数据库
df.to_sql(
'Employees',
conn,
if_exists='append',
index=False,
schema='dbo' # 指定架构,默认是 dbo
)
print(f"成功将 DataFrame 中的 {len(df)} 条记录写入数据库。")
except pyodbc.Error as e:
print(f"数据库操作失败: {e}")
except Exception as e:
print(f"发生错误: {e}")
finally:
if 'conn' in locals() and conn:
conn.close()
print("数据库连接已关闭。")
最佳实践和注意事项
-
始终使用参数化查询:如场景一所示,永远不要用 Python 的字符串拼接来构建 SQL 语句(
f"INSERT INTO ... VALUES ('{value1}', ...)"),这极易受到 SQL 注入攻击,参数化查询是防止此问题的标准做法。 -
使用
with语句管理连接:with语句可以确保连接在使用完毕后被自动关闭,即使在代码块中发生了异常,这是一种更安全、更 Pythonic 的方式。# 使用 with 语句的示例 connection_string = '...' with pyodbc.connect(connection_string) as conn: with conn.cursor() as cursor: cursor.execute("SELECT * FROM Employees") for row in cursor: print(row) # 连接在这里会自动关闭 -
事务管理:默认情况下,
pyodbc是在自动提交模式下,这意味着每条execute语句都会立即提交,但在进行一系列相关操作时,最好手动开始、提交和回滚事务,以保证数据一致性。try: conn = pyodbc.connect(connection_string) conn.autocommit = False # 关闭自动提交 cursor = conn.cursor() # 执行多个操作... cursor.execute("...") cursor.execute("...") conn.commit() # 所有操作成功后,一次性提交 except Exception as e: conn.rollback() # 任一操作失败,全部回滚 -
处理大数据量:对于非常大的 DataFrame 或数据集,
to_sql方法可能会消耗大量内存,可以考虑分块插入:# 分块插入 chunk_size = 1000 for i in range(0, len(df), chunk_size): chunk = df[i:i + chunk_size] chunk.to_sql('Employees', conn, if_exists='append', index=False) -
连接字符串:
DRIVER的名称(如ODBC Driver 18 for SQL Server)必须与你系统上安装的驱动完全匹配,如果不匹配,会报错 "Data source name not found"。
希望这份详细的指南能帮助你在 Python 中顺利地将数据存储到 SQL Server!
