이야기 배경 : 나는 금융 작업 (안 개발자, 그래서 도움이 매우 감사합니다) , 내 부서가 현재의 최대한 자동화 엑셀 및 VBA에 크게 의존 우리의 임무. 이 회사는 파이썬 배포판을 검증했고 이제는 사용할 수있게되었으므로 방금 시도해 보았습니다.로드 CSV는 pyodbc와 팬더를 사용하여 .MDB하는
과제 : 내 첫 번째 과제는 CSV는 MSAcess 데이터베이스에 파일을로드 할 수 있었다 (아니 우리 모두가 충분히 개발 도구 및 데시벨을 사용하여 순수하게 작동, 그래서 모두를 위해 일을 쉽게하기 위해 필요에 기술 Savy은이기 때문에) .
내가 인터넷에 둘러 볼 수있는 여러 가지 ppl 코드의 조각을 발견 할 수는 있지만 작동하고 있지만 그것이 Frankenstein이되었다는 것을 알 수 있습니다. 이 일을 무슨
이유 :
- 로드 CSV 변수
- 지구 밖으로 첫번째 행에 (소스 파일이 정말를 CSV 아니기 때문에, 파일의 시작에서 쓰레기 행이)
- 임시 드라이브의 CSV로 내보내기
- 팬더를 사용하여 SQLite에 CSV로드 (팬더가 각 열의 데이터 유형을 추론 할 수 있기 때문에)
- 수출
TL (매우 느린) 행에 의해 테이블 행을 .MDB 할 pyodbc에게
현재 코드는 다른 코드의 패치 워크이며,보기 흉하고 느립니다. 더 효율적으로 만들거나 최적화하려면 어떻게해야합니까?
목표는 올바른 데이터 형식을 사용하여 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 파일을 구문 분석하고 Access에서 수행하지 않고 .mdb에로드 할 수있는 기능을 갖추어 야간에 자동으로 실행되는 스크립트를 가질 수 있었으며 나중에 읽기에서 향상시킬 수있었습니다. csv 파일 목록과 해당 .mdb 및 테이블 이름 목록이있는 테이블입니다. 다소 위의 코드가 작동하지만 속도가 느립니다. 특히 각 행에 대한 삽입 쿼리를 실행하는 마지막 부분입니다. – ddensa