Фоновая история: Я работаю по финансам (не разработчик, так что помощь очень ценится), мой отдел в настоящее время в значительной степени зависит от первенствует и VBA для автоматизации в максимально возможной степени наши задачи. Компания просто проверила дистрибутив python, и теперь нам разрешено использовать его, поэтому я просто подумал о том, чтобы попробовать.нагрузки CSV для .mdb с помощью pyodbc и панд
Задача: Моя первая задача была, чтобы загрузить CSV-файла в базу данных MSAcess (потому что не все из нас технологий Сави достаточно для работы исключительно с помощью средства разработки и БД, так что нужно, чтобы сделать вещи легко для всех) ,
Я мог бы найти кусочки разных кода ppl в Интернете, которые я мог бы собрать вместе, это работает, но, оказывается, это стало Frankenstein.
Что он делает и почему:
- Загрузить CSV в переменную
- Strip из первых строк (потому что исходный файл не НАСТОЯЩИЙ CSV, есть мусорные строки в начале файла)
- Экспорт в CSV в темпе диске (потому что не мог понять, как загрузить с пандой из переменных)
- загрузить CSV в SQLite с помощью панды (потому что панды способны выводить тип данных каждого столбца)
- Экспорт "создать таблицу" заявление переменной
- Создать таблицу в .mdb файле с помощью pyodbc
- Загрузить данные в .mdb таблицы по строкам (это очень медленно)
TL; DR:
Текущий код - это пэчворк разных кодов, он уродливый и медленный, что бы вы изменили, чтобы сделать его более эффективным/оптимизировать?
Цель состоит в том, чтобы иметь код, который загружает CSV в .mdb, возможно, используя правильный тип данных для создания таблицы.
import csv
import pyodbc
import pandas
import pandas.io.sql
import sqlite3
import tempfile
import time
import string
def load_csv_to_access(access_path, table_name, csv_path, skip_rows):
# open CSV file, load to a variable, output to a temp file excluding first non csv rows
#
filename = csv_path
csv_file = open(filename)
txt = ""
for index, line in enumerate(csv_file, start=0): #Skip first rows
if index > skip_rows:
txt += line
csv_file.close()
temp_filename = time.strftime("%y%m%d%H%M%S") + '.csv'
temp_filepath = tempfile.gettempdir() + '\\' + temp_filename
file = open(temp_filepath, 'w+')
file.write(txt) # create temp csv
file.close()
print "1: temp file created: " + temp_filepath
# Use panda and SQLite to infer data type of CSV fields
#
df = pandas.read_csv(temp_filepath, delimiter=';', index_col=0, engine='python')
df.columns = df.columns.str.replace(' ', '_')
# connect to in-memory database for testing; replace `:memory:` w/ file path
con = sqlite3.connect('db.sqlite')
df.to_sql(table_name, con, if_exists='replace')
sqlite_query_string = "SELECT sql FROM sqlite_master where name = '" + table_name + "'"
create_table_tuple = con.execute(sqlite_query_string).fetchone()
con.close()
create_table_string = create_table_tuple[0]
print "2: Data type inferred"
#Connect to AccessDB and load temp CSV
#
access_string = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + access_path + "; Provider=MSDASQL;"
print access_string
con = pyodbc.connect(access_string)
cur = con.cursor()
cur.execute(create_table_string)
con.commit()
print "3: MS Access table created: " + table_name
print "4: Loading data rows:"
with open(temp_filepath, 'r') as f:
reader = csv.reader(f, delimiter=';')
columns = next(reader)
query = "insert into " + table_name + "({0}) values ({1})"
query = query.format(','.join(columns).replace(' ', '_'), ','.join(
'?' * len(columns))) #Create insert query (replace empty space by underscore to avoid db issues)
for index, data in enumerate(reader, start=0):
cur.execute(query, data) #Insert row by row
print index # For debugging
cur.commit()
con.close()
Спасибо, как вы, ребята, намного лучше меня, были бы признательны за любые предложения.
Задайте это по адресу http://codereview.stackexchange.com/ – Gustav
Доступ также может вызывать типы столбцов. Вы используете для этого панды, потому что это делает лучшую работу, или просто потому, что это то, что вы нашли во время поиска? –
@GordThompson Потому что это то, что я мог найти во время поиска, который не требовал сделать это от Access или даже открыть его. Мой план состоял в том, чтобы иметь функцию, которая могла бы анализировать различные CSV-файлы и загружать их в .mdb, без необходимости делать это из Access, поэтому у меня мог бы быть сценарий, который запускается автоматически в течение ночи, а позже, возможно, улучшится, прочитав из таблицу со списком файлов csv и соответствующее .mdb и имя таблицы. Код выше kinda работает, но он медленный, особенно последняя часть, где он запускает запрос вставки для каждой строки. – ddensa