如何通过executemany()语句转换pandas数据帧以进行插入?

问题描述 投票:11回答:3

我有一个相当大的pandas dataframe - 50左右标题和几十万行数据 - 我希望使用ceODBC模块将这些数据传输到数据库。以前我使用的是pyodbc并在for循环中使用一个简单的执行语句,但这是非常长的(每10分钟1000条记录)......

我现在正在尝试一个新的模块,我正在尝试引入executemany(),虽然我不太确定参数序列的含义是什么:

    cursor.executemany("""insert into table.name(a, b, c, d, e, f) 
values(?, ?, ?, ?, ?), sequence_of_parameters)

它应该看起来像一个通过每个标题的常量列表

    ['asdas', '1', '2014-12-01', 'true', 'asdasd', 'asdas', '2', 
'2014-12-02', 'true', 'asfasd', 'asdfs', '3', '2014-12-03', 'false', 'asdasd']
  • 这是三行的例子

或者需要什么格式?

作为另一个相关的问题,我怎样才能将常规的pandas数据帧转换为这种格式?

谢谢!

python database pandas executemany
3个回答
13
投票

你可以试试这个:

cursor.executemany(sql_str, your_dataframe.values.tolist())

希望能帮助到你。


6
投票

我最终设法搞清楚了。因此,如果你想使用我使用的模块ceODBC写入数据库的Pandas Dataframe,代码为:

(使用all_data作为数据帧)将数据帧值映射到字符串并将每一行存储为元组列表中的元组

for r in all_data.columns.values:
    all_data[r] = all_data[r].map(str)
    all_data[r] = all_data[r].map(str.strip)   
tuples = [tuple(x) for x in all_data.values]

对于元组列表,将所有空值表示符(已在上面的转换中作为字符串捕获)更改为可以传递给结束数据库的null类型。这对我来说是一个问题,可能不适合你。

string_list = ['NaT', 'nan', 'NaN', 'None']

def remove_wrong_nulls(x):
    for r in range(len(x)):
        for i,e in enumerate(tuples):
            for j,k in enumerate(e):
                if k == x[r]:
                    temp=list(tuples[i])
                    temp[j]=None
                    tuples[i]=tuple(temp)

remove_wrong_nulls(string_list)

创建与数据库的连接

cnxn=ceODBC.connect('DRIVER={SOMEODBCDRIVER};DBCName=XXXXXXXXXXX;UID=XXXXXXX;PWD=XXXXXXX;QUIETMODE=YES;', autocommit=False)
cursor = cnxn.cursor()

定义一个函数,将元组列表转换为new_list,它是元组列表的进一步索引,分为1000块。这对我来说是必要的,可以将数据传递给SQL Query不能超过1MB的数据库。

def chunks(l, n):
    n = max(1, n)
    return [l[i:i + n] for i in range(0, len(l), n)]

new_list = chunks(tuples, 1000)

定义您的查询。

query = """insert into XXXXXXXXXXXX("XXXXXXXXXX", "XXXXXXXXX", "XXXXXXXXXXX") values(?,?,?)"""

运行包含1000个组中的元组列表的new_list并执行executemany。通过提交和关闭连接来实现这一点,就是这样:)

for i in range(len(new_list)):
    cursor.executemany(query, new_list[i])
cnxn.commit()
cnxn.close()

2
投票

可能有点迟到回答这个问题,但也许它仍然可以帮助某人。许多ODBC没有实现executemany()。确实有它的其中一个是MySQL。当他们参考参数序列时,他们的意思是:

parameters=[{'name':'Jorge', 'age':22, 'sex':'M'}, 
            {'name':'Karen', 'age':25, 'sex':'F'}, 
            {'name':'James', 'age':29, 'sex':'M'}]

对于查询语句,它看起来像:

SQL = INSERT IGNORE INTO WORKERS (NAME, AGE, SEX) VALUES (%(name)s, %(age)s, %(sex)s)

看起来你到了那里。虽然我想指出一些事情,但是如果有帮助的话:pandas有一个to_sql函数,如果你提供了连接器对象,它会插入到数据库中,并且也会对数据进行分块。

为了从pandas数据帧中快速创建一系列参数,我发现以下两种方法很有用:

# creates list of dict, list of parameters
# REF: https://groups.google.com/forum/#!topic/pydata/qna3Z3WmVpM
parameters = [df.iloc[line, :].to_dict() for line in range(len(df))]

# Cleaner Way
parameters = df.to_dict(orient='records')
© www.soinside.com 2019 - 2024. All rights reserved.