Python使用pyodbc访问数据库操作方法详解


Posted in Python onJuly 05, 2018

本文实例讲述了Python使用pyodbc访问数据库操作方法。

数据库连接

数据库连接网上大致有两种方法,一种是使用pyodbc,另一种是使用win32com.client,测试了很多遍,最终只有pyodbc成功,而且比较好用,所以这里只介绍这种方法

工具库安装

在此基础上安装pyodbc工具库,在cmd窗口执行如下语句安装

pip install pyodbc

如果安装了anaconda也可以使用conda install pyodbc

分享给大家供大家参考,具体如下:

检验是否可以正常连接数据库检查是否有一个Microsoft Access ODBC驱动程序可用于你的Python环境(在Windows上)的方法:

>>> import pyodbc
>>>[x for x in pyodbc.drivers() if x.startswith('Microsoft Access Driver')]

如果你看到一个空列表,那么您正在运行64位Python,并且需要安装64位版本的“ACE”驱动程序。如果您只看到['Microsoft Access Driver (*.mdb)']并且需要使用.accdb文件,那么您需要安装32位版本的“ACE”驱动程序

安装64位的ODBC 驱动器:

64位ODBC驱动器的下载地址 https://www.microsoft.com/en-us/download/details.aspx?id=13255
直接安装会报错,所以我们需要修改一下文件AccessDatabaseEngine_X64.exe,先对其进行解压,然后打开AccessDatabaseEngine_X64文件夹,有一个AceRedist.msi文件。用Orca软件将AceRedist.msi打开,找到找到LaunchCondition里面的BLOCKINSTALLATION,删除那一行数据并进行保存。然后再运行AceRedist.msi,就可以把64位的ODBC 驱动器安装成功。

如果感觉上面的操作比较麻烦,可以直接下载三水点靠木小编已经处理过的版本。

下载地址:https://3water.com/softs/695978.html

注意:

1、不用配置数据源
2、Orcad的下载地址 https://3water.com/softs/16217.html

下面是经过三水点靠木小编测试过的代码

access是2000的,理论上2010也可以。

import pyodbc 

DBfile = r"F:\python\caiji.mdb" # 数据库文件需要带路径
print(DBfile)
conn = pyodbc.connect(r"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+ DBfile +";Uid=;Pwd=;") 
cursor = conn.cursor() 
SQL = "SELECT * from sites;" 
for row in cursor.execute(SQL): 
 print(row) 
cursor.close() 
conn.close()

完整测试代码

# -*-coding:utf-8-*-
import pyodbc

# 连接数据库(不需要配置数据源),connect()函数创建并返回一个 Connection 对象
cnxn = pyodbc.connect(r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=.\data\goods.mdb')
# cursor()使用该连接创建(并返回)一个游标或类游标的对象
crsr = cnxn.cursor()

# 打印数据库goods.mdb中的所有表的表名
print('`````````````` goods ``````````````')
for table_info in crsr.tables(tableType='TABLE'):
  print(table_info.table_name)


l = crsr.execute("SELECT * from goods WHERE goodsId='0001'")# [('0001', '扇叶', 20, 'A公司', 'B公司', 2000, 2009)]

rows = crsr.execute("SELECT currentStock from goods") # 返回的是一个元组
for item in rows:
  print(item)

l = crsr.execute("UPDATE users SET username='lind' WHERE password='123456'")
print(crsr.rowcount) # 想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。

# 修改数据库中int类型的值
value = 10
SQL = "UPDATE goods " \
   "SET lowestStock=" + str(value) + " " \
   "WHERE goodsId='0005'"

# 删除表users
crsr.execute("DROP TABLE users")
# 创建新表 users
crsr.execute('CREATE TABLE users (login VARCHAR(8),userid INT, projid INT)')
# 给表中插入新数据
crsr.execute("INSERT INTO users VALUES('Linda',211,151)")

''''''
# 更新数据
crsr.execute("UPDATE users SET projid=1 WHERE userid=211")

# 删除行数据
crsr.execute("DELETE FROM goods WHERE goodNum='0001'")

# 打印查询的结果
for row in crsr.execute("SELECT * from users"):
  print(row)


# 提交数据(只有提交之后,所有的操作才会对实际的物理表格产生影响)
crsr.commit()
crsr.close()
cnxn.close()

1、连接数据库

1)直接连接数据库和创建一个游标(cursor)

cnxn =pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass')
cursor =cnxn.cursor()

2)使用DSN连接。通常DSN连接并不需要密码,还是需要提供一个PSW的关键字。

cnxn =pyodbc.connect('DSN=test;PWD=password')
cursor =cnxn.cursor()

关于连接函数还有更多的选项,可以在pyodbc文档中的 connect funtion 和 ConnectionStrings查看更多的细节

2、数据查询(SQL语句为 select ...from..where

1)所有的SQL语句都用cursor.execute函数运行。如果语句返回行,比如一个查询语句返回的行,你可以通过游标的fetch函数来获取数据,这些函数有(fetchone,fetchall,fetchmany).如果返回空行,fetchone函数将返回None,而fetchallfetchmany将返回一个空列。

cursor.execute("select user_id, user_name from users")
row =cursor.fetchone()
if row:
 printrow

2)Row这个类,类似于一个元组,但是他们也可以通过字段名进行访问。

cursor.execute("select user_id, user_name from users")
row =cursor.fetchone()
print'name:', row[1]  # access by column index
print'name:', row.user_name # or access by name

3)如果所有的行都被检索完,那么fetchone将返回None.

while 1:
 row= cursor.fetchone()
 ifnot row:
 break
 print'id:', row.user_id

4)使用fetchall函数时,将返回所有剩下的行,如果是空行,那么将返回一个空列。(如果有很多行,这样做的话将会占用很多内存。未读取的行将会被压缩存放在数据库引擎中,然后由数据库服务器分批发送。一次只读取你需要的行,将会大大节省内存空间)

cursor.execute("select user_id, user_name from users")
rows =cursor.fetchall()
for row in rows:
 printrow.user_id, row.user_name

5)如果你打算一次读完所有数据,那么你可以使用cursor本身。

cursor.execute("select user_id, user_name from users"):
for row in cursor:
 printrow.user_id, row.user_name

6)由于cursor.execute返回一个cursor,所以你可以把上面的语句简化成:

for row in cursor.execute("select user_id, user_name from users"):
 printrow.user_id, row.user_name

7)有很多SQL语句用单行来写并不是很方便,所以你也可以使用三引号的字符串来写:

cursor.execute("""
  select user_id, user_name
   from users
  where last_logon < '2001-01-01'
   and bill_overdue = 'y'
  """)

3、参数

1)ODBC支持在SQL语句中使用一个问号来作为参数。你可以在SQL语句后面加上值,用来传递给SQL语句中的问号。

cursor.execute("""
  select user_id, user_name
   from users
  where last_logon < ?
   and bill_overdue = ?
  """,'2001-01-01','y')

这样做比直接把值写在SQL语句中更加安全,这是因为每个参数传递给数据库都是单独进行的。如果你使用不同的参数而运行同样的SQL语句,这样做也更加效率。

3)python DB API明确说明多参数时可以使用一个序列来传递。pyodbc同样支持:

cursor.execute("""
  select user_id, user_name
   from users
  where last_logon < ?
   and bill_overdue = ?
  """, ['2001-01-01','y'])
cursor.execute("select count(*) as user_count from users where age > ?",21)
row =cursor.fetchone()
print'%d users' %row.user_count

4、数据插入

1)数据插入,把SQL插入语句传递给cursorexecute函数,可以伴随任何需要的参数。

cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
cnxn.commit()
cursor.execute("insert into products(id, name) values (?, ?)",'pyodbc', 'awesome library')
cnxn.commit()

注意调用cnxn.commit()函数:你必须调用commit函数,否者你对数据库的所有操作将会失效!当断开连接时,所有悬挂的修改将会被重置。这很容易导致出错,所以你必须记得调用commit函数。

5、数据修改和删除

1)数据修改和删除也是跟上面的操作一样,把SQL语句传递给execute函数。但是我们常常想知道数据修改和删除时,到底影响了多少条记录,这个时候你可以使用cursor.rowcount的返回值。

cursor.execute("delete from products where id <> ?",'pyodbc')
printcursor.rowcount, 'products deleted'
cnxn.commit()

2)由于execute函数总是返回cursor,所以有时候你也可以看到像这样的语句:(注意rowcount放在最后面)

deleted =cursor.execute("delete from products where id <> 'pyodbc'").rowcount
cnxn.commit()

同样要注意调用cnxn.commit()函数

6、小窍门

1)由于使用单引号的SQL语句是有效的,那么双引号也同样是有效的:

deleted =cursor.execute("delete from products where id <> 'pyodbc'").rowcount

2)假如你使用的是三引号,那么你也可以这样使用:

deleted =cursor.execute("""
    delete
    from products
    where id <> 'pyodbc'
    """).rowcount

3)有些数据库(比如SQL Server)在计数时并没有产生列名,这种情况下,你想访问数据就必须使用下标。当然你也可以使用"as"关键字来取个列名(下面SQL语句的"as name-count")

row =cursor.execute("select count(*) as user_count from users").fetchone()
print'%s users' %row.user_count

4)假如你只是需要一个值,那么你可以在同一个行局中使用fetch函数来获取行和第一个列的所有数据。

count =cursor.execute("select count(*) from users").fetchone()[0]
print'%s users' %count

如果列为空,将会导致该语句不能运行。fetchone()函数返回None,而你将会获取一个错误:NoneType不支持下标。如果有一个默认值,你能常常使用ISNULL,或者在SQL数据库直接合并NULLs来覆盖掉默认值。

maxid =cursor.execute("select coalesce(max(id), 0) from users").fetchone()[0]

在这个例子里面,如果max(id)返回NULL,coalesce(max(id),0)将导致查询的值为0。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python 将字符串转换成字典dict
Mar 24 Python
为python设置socket代理的方法
Jan 14 Python
Python脚本暴力破解栅栏密码
Oct 19 Python
Pyhton中单行和多行注释的使用方法及规范
Oct 11 Python
python如何求解两数的最大公约数
Sep 27 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
Apr 11 Python
利用python实现周期财务统计可视化
Aug 25 Python
Python进度条的制作代码实例
Aug 31 Python
简单了解Python读取大文件代码实例
Dec 18 Python
PyQt5多线程防卡死和多窗口用法的实现
Sep 15 Python
python tkinter模块的简单使用
Apr 07 Python
Python使用scapy模块发包收包
May 07 Python
如何优雅地处理Django中的favicon.ico图标详解
Jul 05 #Python
解决pandas中读取中文名称的csv文件报错的问题
Jul 04 #Python
解决Python pandas df 写入excel 出现的问题
Jul 04 #Python
python处理数据,存进hive表的方法
Jul 04 #Python
利用Pandas读取文件路径或文件名称包含中文的csv文件方法
Jul 04 #Python
使用pandas read_table读取csv文件的方法
Jul 04 #Python
使用Numpy读取CSV文件,并进行行列删除的操作方法
Jul 04 #Python
You might like
php记录代码执行时间(实现代码)
2013/07/05 PHP
php中把美国时间转为北京时间的自定义函数分享
2014/07/28 PHP
nginx+thinkphp下解决不支持pathinfo模式
2015/07/01 PHP
php 数组字符串搜索array_search技巧
2016/07/05 PHP
php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
2016/12/23 PHP
PHP变量的作用范围实例讲解
2020/12/22 PHP
精通Javascript系列之数据类型 字符串
2011/06/08 Javascript
ie8 不支持new Date(2012-11-10)问题的解决方法
2013/07/31 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
使用Plupload实现直接上传附件至七牛云存储
2014/12/26 Javascript
jquery实现简单的自动播放幻灯片效果
2015/06/13 Javascript
javascript实现根据时间段显示问候语的方法
2015/06/18 Javascript
Javascript基础知识盲点总结之函数
2016/05/15 Javascript
[03:09]2014DOTA2国际邀请赛 Mushi前队友送上祝福
2014/07/12 DOTA
python实现zencart产品数据导入到magento(python导入数据)
2014/04/03 Python
python实现查找两个字符串中相同字符并输出的方法
2015/07/11 Python
Zabbix实现微信报警功能
2016/10/09 Python
一份python入门应该看的学习资料
2018/04/11 Python
Python闭包函数定义与用法分析
2018/07/20 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
在python中对变量判断是否为None的三种方法总结
2019/01/23 Python
CSS3制作Dropdown下拉菜单的方法
2015/07/18 HTML / CSS
数百万免费的图形资源:Freepik
2020/09/21 全球购物
环境科学专业个人求职的自我评价
2013/11/28 职场文书
临床医师专业个人自我评价
2014/01/08 职场文书
倡议书格式范文
2014/04/14 职场文书
《歌唱二小放牛郎》教学反思
2014/04/19 职场文书
营销部内勤岗位职责
2014/04/30 职场文书
党员个人对照检查材料思想汇报
2014/09/16 职场文书
2015年教师党员自我评价材料
2015/03/04 职场文书
2015年工商所工作总结
2015/05/21 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
读书笔记怎么写
2015/07/01 职场文书
如何用PHP实现分布算法之一致性哈希算法
2021/05/26 PHP
手残删除python之后的补救方法
2021/06/26 Python
react中useState使用:如何实现在当前表格直接更改数据
2022/08/05 Javascript