[PYTHON] sqlalchemy를 사용하여 csv 파일을 데이터베이스에로드
PYTHONsqlalchemy를 사용하여 csv 파일을 데이터베이스에로드
파이썬으로 프로그래밍하는 법을 배우려고합니다. 나는 csv 파일을 데이터베이스에 보내고 싶다. 사용하는 것이 좋습니다.
해결법
-
==============================
1.SQLAlchemy의 힘으로 인해, 나는 또한 프로젝트에서 그것을 사용하고있다. 권력은 SQL 문을 하드 코딩하는 대신 데이터베이스에 "말하는"객체 지향 방식에서 비롯됩니다. SQL 문은 관리하기가 어려울 수 있습니다. 말할 것도없이, 그것은 훨씬 빠릅니다.
SQLAlchemy의 힘으로 인해, 나는 또한 프로젝트에서 그것을 사용하고있다. 권력은 SQL 문을 하드 코딩하는 대신 데이터베이스에 "말하는"객체 지향 방식에서 비롯됩니다. SQL 문은 관리하기가 어려울 수 있습니다. 말할 것도없이, 그것은 훨씬 빠릅니다.
퉁명스럽게 질문에 대답하려면 예! SQLAlchemy를 사용하여 CSV에서 데이터베이스에 데이터를 저장하는 것이 핵심입니다. 다음은 완전한 예제입니다 (SQLAlchemy 1.0.6과 Python 2.7.6을 사용했습니다).
from numpy import genfromtxt from time import time from datetime import datetime from sqlalchemy import Column, Integer, Float, Date from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker def Load_Data(file_name): data = genfromtxt(file_name, delimiter=',', skip_header=1, converters={0: lambda s: str(s)}) return data.tolist() Base = declarative_base() class Price_History(Base): #Tell SQLAlchemy what the table name is and if there's any table-specific arguments it should know about __tablename__ = 'Price_History' __table_args__ = {'sqlite_autoincrement': True} #tell SQLAlchemy the name of column and its attributes: id = Column(Integer, primary_key=True, nullable=False) date = Column(Date) opn = Column(Float) hi = Column(Float) lo = Column(Float) close = Column(Float) vol = Column(Float) if __name__ == "__main__": t = time() #Create the database engine = create_engine('sqlite:///csv_test.db') Base.metadata.create_all(engine) #Create the session session = sessionmaker() session.configure(bind=engine) s = session() try: file_name = "t.csv" #sample CSV file used: http://www.google.com/finance/historical?q=NYSE%3AT&ei=W4ikVam8LYWjmAGjhoHACw&output=csv data = Load_Data(file_name) for i in data: record = Price_History(**{ 'date' : datetime.strptime(i[0], '%d-%b-%y').date(), 'opn' : i[1], 'hi' : i[2], 'lo' : i[3], 'close' : i[4], 'vol' : i[5] }) s.add(record) #Add all the records s.commit() #Attempt to commit all the records except: s.rollback() #Rollback the changes on error finally: s.close() #Close the connection print "Time elapsed: " + str(time() - t) + " s." #0.091s
(참고 : 이것이 반드시 "최선"이라고는 할 수 없지만이 형식은 초보자에게 매우 읽기 쉽고 매우 빠릅니다 : 삽입 된 251 개의 레코드는 0.091입니다!)
제 생각에는 당신이 그것을 하나씩 살펴 보시면, 사용하는 것이 바람이 될 것입니다. SQL 문이 부족하다는 것을 알 수 있습니다 - 만세! 또한 numpy를 사용하여 두 줄의 CSV 내용을로드 할 자유를 가졌지 만 원하는 경우 CSV 내용없이로드 할 수 있습니다.
기존 방식과 비교하고 싶다면 다음을 참조하십시오.
import sqlite3 import time from numpy import genfromtxt def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d def Create_DB(db): #Create DB and format it as needed with sqlite3.connect(db) as conn: conn.row_factory = dict_factory conn.text_factory = str cursor = conn.cursor() cursor.execute("CREATE TABLE [Price_History] ([id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, [date] DATE, [opn] FLOAT, [hi] FLOAT, [lo] FLOAT, [close] FLOAT, [vol] INTEGER);") def Add_Record(db, data): #Insert record into table with sqlite3.connect(db) as conn: conn.row_factory = dict_factory conn.text_factory = str cursor = conn.cursor() cursor.execute("INSERT INTO Price_History({cols}) VALUES({vals});".format(cols = str(data.keys()).strip('[]'), vals=str([data[i] for i in data]).strip('[]') )) def Load_Data(file_name): data = genfromtxt(file_name, delimiter=',', skiprows=1, converters={0: lambda s: str(s)}) return data.tolist() if __name__ == "__main__": t = time.time() db = 'csv_test_sql.db' #Database filename file_name = "t.csv" #sample CSV file used: http://www.google.com/finance/historical?q=NYSE%3AT&ei=W4ikVam8LYWjmAGjhoHACw&output=csv data = Load_Data(file_name) #Get data from CSV Create_DB(db) #Create DB #For every record, format and insert to table for i in data: record = { 'date' : i[0], 'opn' : i[1], 'hi' : i[2], 'lo' : i[3], 'close' : i[4], 'vol' : i[5] } Add_Record(db, record) print "Time elapsed: " + str(time.time() - t) + " s." #3.604s
(참고 : "구식"방법이라 할지라도 이것이 최선의 방법은 아니지만 SQLAlchemy 방식과 "구식"방식의 번역은 "1 대 1"로 매우 읽기 쉽습니다.
SQL 문을 확인하십시오. 하나는 테이블을 작성하고, 다른 하나는 레코드를 삽입합니다. 또한 긴 SQL 문자열과 간단한 클래스 속성 추가를 유지하는 것이 약간 번거롭다는 것을 알아 두십시오. 좋아하는 SQLAlchemy 지금까지?
물론 당신의 외래 질의에 관해서는. SQLAlchemy도이 작업을 수행 할 수 있습니다. 다음은 외부 키 할당 (foreignKey 클래스가 sqlalchemy 모듈에서도 가져 왔다고 가정 할 때)과 같은 클래스 속성의 예입니다.
class Asset_Analysis(Base): #Tell SQLAlchemy what the table name is and if there's any table-specific arguments it should know about __tablename__ = 'Asset_Analysis' __table_args__ = {'sqlite_autoincrement': True} #tell SQLAlchemy the name of column and its attributes: id = Column(Integer, primary_key=True, nullable=False) fid = Column(Integer, ForeignKey('Price_History.id'))
"fid"열을 Price_History의 id 열에 대한 외래 키로 지정합니다.
희망이 도움이됩니다!
-
==============================
2.CSV가 상당히 큰 경우 INSERT를 사용하는 것은 효과가 없습니다. 기저부마다 다른 대량로드 메커니즘을 사용해야합니다. 예 : PostgreSQL에서는 "COPY FROM"메소드를 사용해야합니다 :
CSV가 상당히 큰 경우 INSERT를 사용하는 것은 효과가 없습니다. 기저부마다 다른 대량로드 메커니즘을 사용해야합니다. 예 : PostgreSQL에서는 "COPY FROM"메소드를 사용해야합니다 :
with open(csv_file_path, 'r') as f: conn = create_engine('postgresql+psycopg2://...').raw_connection() cursor = conn.cursor() cmd = 'COPY tbl_name(col1, col2, col3) FROM STDIN WITH (FORMAT CSV, HEADER FALSE)' cursor.copy_expert(cmd, f) conn.commit()
-
==============================
3.나는 똑같은 문제를 겪었고 판다로 2 단계 과정을 사용하는 것이 역설적으로 더 쉬운 것으로 나타났습니다.
나는 똑같은 문제를 겪었고 판다로 2 단계 과정을 사용하는 것이 역설적으로 더 쉬운 것으로 나타났습니다.
import pandas as pd with open(csv_file_path, 'r') as file: data_df = pd.read_csv(file) data_df.to_sql('tbl_name', con=engine, index=True, index_label='id', if_exists='replace')
내 접근법은이 방법과 유사하지만, 어떻게 든 Google이이 스레드로 나를 대신 보내므로 공유 할 것이라고 생각했습니다.
from https://stackoverflow.com/questions/31394998/using-sqlalchemy-to-load-csv-file-into-a-database by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬에서 다른 쓰레드가 덮어 쓰지 않고 raw_input ()에서 입력 값을 읽음 (0) | 2018.11.26 |
---|---|
[PYTHON] 엑셀 파일에 사전 값 쓰기 (0) | 2018.11.26 |
[PYTHON] Pandas Dataframe : NaN을 행 평균으로 바꾸기 (0) | 2018.11.26 |
[PYTHON] 장고 프록시 모델과 ForeignKey (0) | 2018.11.26 |
[PYTHON] 파이썬 틸드 단항 연산자 부정으로 numpy bool 배열 (0) | 2018.11.26 |