在批量插入postgresql時想使用同Mysql的語法時發現並不能使用:
cursor.executemany("INSERT INTO persons VALUES (%d, %s, %s)",[(1, 'John Smith', 'John Doe'),(2, 'Jane Doe', 'Joe Dog'),(3, 'Mike T.', 'Sarah H.')])
難道只能寫成這樣嗎:
insert into A values(**********),(*************),(*****************)
但是這種方法及麻煩而且還不快
后發現了copy_from()這個神奇的方法!
在參考:https://blog.csdn.net/rongyongfeikai2/article/details/17935139 這位仁兄的博客后一直失敗,提示缺少字段.這就很難受了,查閱所有百度的資料無解,大部分都是來回抄襲,毫無新意,這里又忍不住要吐槽百度了.
只能去Google看看了,進入pg的官網才豁然開朗
http://initd.org/psycopg/docs/cursor.html
COPY_FROM說明:
copy_from
(file,table,sep ='\ t',null ='\\ N',size = 8192,columns = None )
從類似文件的目標 文件中讀取數據 ,將它們附加到名為 table的表中。
- file - 從中讀取數據的類文件對象。它必須具有
read()
和readline()
方法。 - table - 要將數據復制到的表的名稱。
- sep - 文件中預期的列分隔符。默認為選項卡。
- null -
NULL
文件中的文本表示。默認為兩個字符串\N
。 - size - 用於從文件中讀取的緩沖區的大小。
- columns - 可以使用要導入的列的名稱進行迭代。長度和類型應與要讀取的文件的內容相匹配。如果未指定,則假定整個表與文件結構匹配。
例:
注意:
表的名稱未引用:如果表名包含大寫字母或特殊字符,則必須使用雙引號引用:不得不說上面哪位仁兄的不嚴謹性了,在批量插入的每個數據之間用<\t>分割,在一條數據的末尾用<\n>分割.
附本人代碼段:
tap = (indent_num, it.get(u'商品編碼'),it.get(u'商品名稱'),it.get(u'批發價'),it.get(u'零售指導價'),it.get(u'需求量'),it.get(u'訂購量'),it.get(u'金額'),it.get(u'預計盈利'),cigarette_price)
values_list.append('\t'.join(tap))s = ''
for value in values_list:
s += value + '\n'cur = self.conn.cursor()
try:
# cur.executemany(insert_sql)
cur.copy_from(StringIO.StringIO(s), table,
columns=('indent_num', 'commodity_code', 'commodity_name', 'rade_price', 'guidance_price',
'requirement', 'order_quantity','amount_of_money','wholesale_price','cigarette_price'))
except Exception as e:
raise e
finally:
self.conn.commit()
print 'done'