当前位置: 首页 > 面试题库 >

使用sqlalchemy将csv文件加载到数据库中

锺离浩慨
2023-03-14
问题内容

我想在数据库中使用csv文件


问题答案:

由于SQLAlchemy的强大功能,我还在项目中使用了它。它的强大功能来自于与数据库“对话”的面向对象的方式,而不是硬编码难以管理的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内容,但是如果您愿意,也可以不使用它。

如果您想与传统方式进行比较,请参考以下完整示例:

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方式与“旧”方式的“一对一”转换。)

注意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列的外键。

希望有帮助!



 类似资料:
  • 我正在通过SSIS将数据从csv文件加载到我的sql表中。是否对从csv文件读取的记录数指定了默认限制? 在加载csv文件时,我的数据流组件只处理5000条记录,尽管它包含5341条记录,如下面的图像所示。我如何修复这个问题?

  • NEO4J2.1.7 试图通过我在CSV中收到的信息大量连接一堆节点,如下所示: PS:我尝试了上面的语法,也尝试了,都没有用(语法错误)

  • 问题内容: 我正在尝试使用Java + Hibernate + Spring将CSV文件加载到mySQL数据库中。我在DAO中使用以下查询来帮助我加载到数据库中: 我有一些想法可以从http://dev.mysql.com/doc/refman/5.1/en/load- data.html 使用它,以及如何从hibernate +spring应用程序将csv文件导入到mysql中? 但是我得到了错

  • 我有多个csv文件保存在一个文件夹中,具有相同的列布局,并希望将其作为pandas中的数据帧加载到python中。 这个问题与这条线索非常相似。 我使用以下代码: 还有更好的解决方案吗? 这需要很多时间。 谢啦

  • 想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。 谁能解释一下“如何使用Spring Hibernate MVC将CSV文件上载到数据库?”

  • 我是一个相对较新的Python用户。解析和处理CSV并将其加载到本地Postgres数据库(在Python中)的最佳方式是什么? 建议我使用CSV库来解析和处理CSV。特别是,手头的任务说: 数据可能有错误(某些行可能是不可解析的),数据可能是重复的,数据可能非常大。