使用Python访问.zip文件中的.mdb数据库

时间:2018-09-19 06:01:10

标签: python zip zipfile

你好,

Edited 19.09.2018 14:38以澄清我的问题

首先,感谢您阅读我的问题!我希望我的问题甚至可以解决,因为我在这项特定任务的研究中找不到任何答案。

上下文:

有一个将测量数据存储在MS Access .mdb文件中的测量系统。文件的典型大小约为100至200 MB,最长的表(约占所需空间的99%)具有约40万至60万个数据集。由于文件很多,它们会以.zip压缩文件的形式打包,以减少所需的空间(例如,压缩:17131406字节,未压缩:245739520字节)。

方法:

如果要评估测量数据,则需要先提取.zip文件:

import zipfile
from zipfile import ZipFile
"""Extract example .zip file into this directory"""

path = "C:/20180730_0931.zip"
archive = zipfile.ZipFile(path, 'r')
archive.extractall(path=None, members=None, pwd=None)

之后,我可以访问提取的数据库:

import pyodbc 
"""Important: 32bit MS driver - 32bit python!"""

cnxn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/20180730_0931.mdb;')
cursor = cnxn.cursor()

cursor.execute("select * from mytable")
for row in cursor.fetchall():
    print(row)

csr = cnxn.cursor()  
csr.close()
del csr
cnxn.close() 

那么,出什么问题了?

由于有多个用户,我认为这是一个不好的解决方案,并且可能会导致仅提取zip文件并随后删除mdb文件的问题。所以我的想法是,将zip文件提取到用户系统上的一个临时文件中。正如@Goyo所指出的,存储临时文件(硬盘驱动器,闪存驱动器,内存文件系统等)的方式有多种。起初,我只是想获得一个可行的解决方案,但是当然,我更喜欢最快的方法。

程序的工作流程可能如下所示:

  1. 选择zip文件并将其解压缩到用户系统上的临时文件中
  2. 使用pyodbc连接到生成的mdb文件并获取所有数据
  3. 关闭连接,删除临时文件并评估测量数据

我尝试使用StringIOzipfile.readtempfile之类的不同方法,但无法使其正常工作。从可能重复的@stovfl链接中,我尝试了zipfile.readtempfile方法的组合,但其余方法似乎都不适合我的问题:

fenxzip = zipfile.ZipFile("C:/20180730_0931.zip", 'r')

fenfile=tempfile.SpooledTemporaryFile(max_size=10000000000,mode='w+b') 
fenfile.write(fenxzip.read(fenxzip.namelist()[0]))

#Yay a temp file... or is it?

fenfile.close()
fenxzip.close()  

更新1-编辑20.09.2018 10:54

由于SpooledTemporaryFile没有名字,我做了以下事情:

import pyodbc
import tempfile
from zipfile import ZipFile

File = "C:/20180730_0931.zip"

mdbzip = zipfile.ZipFile(File, 'r')

mdbtemp=tempfile.TemporaryFile(mode='w+b')
mdbtemp.write(mdbzip.read(mdbzip.namelist()[0]))

MDB = mdbtemp.name; DRV = '{Microsoft Access Driver (*.mdb)}'; PWD = ''

# connect to db
con = pyodbc.connect('DRIVER={};DBQ={};PWD={}'.format(DRV,MDB,PWD))
cur = con.cursor()

# run a query and get the results 
SQL = 'SELECT * FROM mytable;'
rows = cur.execute(SQL).fetchall()
for row in rows:
    print(row)
cur.close()
con.close()

mdbtemp.close()
mdbzip.close()    

在这种情况下,我有一个命名的临时文件,但出现错误消息,该文件已被使用:

pyodbc.Error: ('HY000', "[HY000] [Microsoft][ODBC Microsoft Access Driver] '(unbekannt)' konnte nicht verwendet werden; Datei wird bereits verwendet. (-1024) (SQLDriverConnect); [HY000] [Microsoft][ODBC Microsoft Access Driver]Allgemeine Warnung Registrierungsschlüssel 'Temporary (volatile) Jet DSN for process 0x30dc Thread 0x2f0 DBC 0x5a10064 Jet' kann nicht geöffnet werden. (1); [HY000] [Microsoft][ODBC Microsoft Access Driver]Allgemeine Warnung Registrierungsschlüssel 'Temporary (volatile) Jet DSN for process 0x30dc Thread 0x2f0 DBC 0x5a10064 Jet' kann nicht geöffnet werden. (1); [HY000] [Microsoft][ODBC Microsoft Access Driver] '(unbekannt)' konnte nicht verwendet werden; Datei wird bereits verwendet. (-1024)")

那么,我的方法根本不可能吗?

0 个答案:

没有答案