Доступ к базе данных .mdb в файле .zip с помощью Python - PullRequest
0 голосов
/ 19 сентября 2018

Привет,

Отредактировано 19.09.2018 14:38, чтобы прояснить мою проблему

Прежде всего, спасибо за чтение моеговопрос!Я надеюсь, что моя проблема даже решаема, так как я не смог найти никаких ответов в своем исследовании по этой конкретной задаче.

Контекст:

Существует система измерениякоторый хранит данные измерений в файлах MS Access .mdb.Типичный размер файлов составляет от 100 до 200 МБ, а самая длинная таблица, занимающая около 99% необходимого пространства, содержит от 400 до 600 000 наборов данных.Поскольку существует много файлов, они упакованы в 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. Подключитесь к полученному файлу mdb с помощью pyodbc и извлеките все данные
  3. Закройте соединение, удалите временный файл и оцените данные измерений

Я пытался использовать разные подходы, такие как StringIO, zipfile.read или tempfile, но не смог заставить его работать.Из возможного дубликата @stovfl, я попробовал комбинацию подхода zipfile.read и tempfile, но остальные, похоже, не подошли к моей проблеме:

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)")

Так может ли быть, что мой подход вообще невозможен?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...