복붙노트

[PYTHON] sqlalchemy를 사용하여 csv 파일을 데이터베이스에로드

PYTHON

sqlalchemy를 사용하여 csv 파일을 데이터베이스에로드

파이썬으로 프로그래밍하는 법을 배우려고합니다. 나는 csv 파일을 데이터베이스에 보내고 싶다. 사용하는 것이 좋습니다.

해결법

  1. ==============================

    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. ==============================

    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. ==============================

    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이이 스레드로 나를 대신 보내므로 공유 할 것이라고 생각했습니다.

  4. from https://stackoverflow.com/questions/31394998/using-sqlalchemy-to-load-csv-file-into-a-database by cc-by-sa and MIT license