Debian11用Python和ODBC操作ACCESS

安装系统支持包:

安装驱动程序管理器unixODBCIODBC

这里以编译安装unixODBC为例。
下载并编译安装最新版本unixODBC-2.3.9

1
2
3
4
5
6
7
wget -P ~/下载/ http://www.unixodbc.org/unixODBC-2.3.9.tar.gz
cd ~/下载
gunzip unixODBC-2.3.9.tar.gz
tar xvf unixODBC-2.3.9.tar
cd unixODBC-2.3.9
./configure --prefix=/usr/local/unixODBC --enable-inicaching --enable-drivers --enable-driver-conf --enable-gui
make && make install

配置odbc.iniodbcinst.ini文件

其中odbc.ini位于~/.odbc.ini,同时因为安装unixODBC时路径配置在/usr/local/unixODBC,因此在/usr/local/unixODBC/etc路径下也存在;
odbcinst.ini位于/etc[重要]和/usr/local/unixODBC/etc路径下.
配置内容参考如下:

配置驱动文件odbcinst.ini

用命令odbcinst -q -d可查看所有驱动 文件

1
2
3
4
5
6
[Access]
Description= ODBC DRIVER FOR Access
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so
Setup=
FileUsage=1
UsageCount=1

其中odbcinst.ini配置中的[MDBToolsODBC]odbc.ini中的Driver = MDBToolsODBC保持一致;
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.solibmdbodbc.so是安装odbc-mdbtools后生成的文件。
路径参考:
在bullseye发行版中amd64硬件架构下的odbc-mdbtools软件包文件清单

配置连接文件odbc.ini

用命令odbcinst -q -s可查看所有 连接 的数据文件

1
2
3
4
5
6
7
8
[test]
Description = ODBC DRIVER FOR Access
Driver = Access
Database = /path/to/yourFile.mdb
Servername = localhost
Username =
Password =
port =

后面用Python操作测试采用以下写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[A1]
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so
Database = /path/to/test/Debian_odbc.mdb

[A2]
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so
Database = /path/to/Debian_odbc.accdb
Servername =
Username =
Password =
port =

[A3]
Driver = Access
Database = /path/to/Debian_odbc.accdb
Servername =
Username =
Password =
port =

标题[A1]和后面python连接代码中DSN=A1语句名称要一致。

安装odbc-mdbtoolsmdbtools

1
2
sudo apt install odbc-mdbtools  # 老包名称为:libmdbodbc1
sudo apt install mdbtools mdbtools-dev libtool-dev # 驱动

或者参照下面步骤编译安装mdbtools

编译安装mdbtools

下载地址

1
2
3
4
5
6
7
8
# 安装支持
sudo apt install libtool automake autoconf bison unixodbc unixodbc-dev gawk
cd /path/to/mdbtools-1.0.0
# 编译
auto-apt run ./configure --prefix=/usr/local/mdbtools --with-unixodbc=/usr/local/unixODBC --enable-ltdl-install --enable-iconvperdriver --with-included-ltdl
make
# 安装并生成安装包
sudo checkinstall

错误待解决: 已经解决
错误提示:
1
2
3
......
checking for SQLGetPrivateProfileString in -lodbcinst... no
configure: error: Could not find SQLGetPrivateProfileString in -lodbcinst

解决:安装系统支持包
1
sudo apt install libtool automake autoconf bison unixodbc unixodbc-dev gawk

参照:mdbtools开源项目地址

安装后测试:

终端上测试:

命令:

1
isql -v test

输出:
1
2
3
4
5
6
7
8
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+

测试sql
1
2
3
4
5
6
7
8
9
10
SQL> select count(*) from login_log
# 输出
+-------------------------------+
| count |
+-------------------------------+
| 464 |
+-------------------------------+
SQLRowCount returns 1
1 rows fetched
SQL>

如图:
debian11_odbc_access.png

Python3.10测试

安装python3支持模块

python3.10没法用pip安装pyodbc,可以安装pypyodbc,以下用python3.10安装pypyodbc做测试

1
pip install pypyodbc

操作语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import pypyodbc

try:
cnxn = pypyodbc.connect('DSN=A1', unicode_results=False)
cur = cnxn.cursor()
# 查询表的 字段长度,字段名
print(len(cur.description))
print(cur.description)
for column_name in cur.description:
print(column_name[0])
cur.execute('SELECT * from tb_usr')
for row in cur.fetchall():
print("这是A1:", row)
cur.close()
cnxn.close()
except Exception as e:
print("链接错误:", e)

print("#"*20,"解决乱码分割线", "#"*20)
### 查询 ###
try:
cnxn = pypyodbc.connect('DSN=A1', unicode_results=False) # 以 bytes 类型输出
cur = cnxn.cursor()
cur.execute('SELECT * from tb_usr')
# for row in cur.fetchall():
for row in cur:
print("这是A1:", row[0], row[1].decode("utf-8"), row[2]) # 字段内容为汉字的转换为字符串
# for row in cur.fetchall():
# print("这是A1:", row)
cur.close()
cnxn.close()
except Exception as e:
print("链接错误:", e)


###### 以下查询和修改均测试失败 ######

### 插入 ###
# try:
cnxn = pypyodbc.connect('DSN=A1', unicode_results=False) # 以 bytes 类型输出
cnxn.autocommit = False
cur = cnxn.cursor() # 创建游标
# keys = "ID,usr_name,usr_age"
# values = "6,'吴六',38"
# insert_sql = "INSERT into tb_usr (ID,usr_name,usr_age) values ({0})".format(values)
# insert_sql = f"INSERT into tb_usr ({keys}) values ({values})"
# insert_sql = """
# INSERT INTO tb_usr([ID], usr_name, usr_age)
# VALUES (6,'wl',38)
# """

# cur.execute(insert_sql)
# params = (6,'吴六',38)
# insert_sql = "INSERT into tb_usr(ID, usr_name, usr_age) values (?,?,?)"
# cur.execute(insert_sql, params)
#
insert_sql = "INSERT Into tb_usr(ID, usr_name, usr_age) values (6,'wuliu',33)"
cur.execute(insert_sql)
# except pypyodbc.DatabaseError as err:
# cnxn.rollback()
# else:
# cnxn.commit()
# finally:
# cnxn.autocommit = True

### 修改 ###
try:
cnxn = pypyodbc.connect('DSN=A1', unicode_results=False) # 以 bytes 类型输出
cnxn.autocommit = False
cur = cnxn.cursor() # 创建游标
update_sql = "UPDATE tb_usr SET usr_name= 'lisi' WHERE ID = 1"
cur.executemany(update_sql)
except pypyodbc.DatabaseError as err:
cnxn.rollback()
else:
cnxn.commit()
print("影响",cur.rowcount,"行")
finally:
cnxn.autocommit = True

###### 插入错误提示
Error at Line : syntax error
syntax error
Got no result for 'INSERT Into tb_usr(ID, usr_name, usr_age) values (6,'wuliu',33)' command
###### 更新错误提示
Error at Line : syntax error
syntax error
Got no result for 'UPDATE tb_usr SET usr_name= 'lisi' WHERE ID = 1' command

结果如图:
debian11_odbc_access-1.png

参考资料:
1、unixODBC DOWNLOAD地址:
2、JET / MS Access database (MDB) tools
3、DB tools ODBC driver
4、软件包mdbtools搜索结果
5、MDB Tools
6、MDB Tools开源项目地址
7、错误码查询sqlstate_status_return_codes
8、在Linux中通过Python脚本访问mdb数据库的方法
9、Access ODBC Driver
10、ODBC Driver Download: Access