我有一个相当大的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数据帧转换为这种格式?
谢谢!
你可以试试这个:
cursor.executemany(sql_str, your_dataframe.values.tolist())
希望能帮助到你。
我最终设法搞清楚了。因此,如果你想使用我使用的模块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()
可能有点迟到回答这个问题,但也许它仍然可以帮助某人。许多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')