在Python3連接mysql要用到pymysql
模塊异旧。
一般用的是普通游標,執(zhí)行select等語句fetchall
時是直接存入內存,有內存不夠的風險。這時可以用SSCursor
长豁,貌似中文叫做流式游標?連接時需要這樣:
conn = pymysql.connect(dbhost, dbuser, dbpass, dbname, charset='utf8')
cur = conn.cursor(pymysql.cursors.SSCursor)
# 也可以cur = pymysql.cursors.SSCursor(conn)
總之忙灼,在執(zhí)行select等sql語句后
cur.execute(sql)
可以通過for
循環(huán)遍歷cur
,此時cur
相當于生成器钝侠,不會直接存儲所有數據该园,而是在循環(huán)時一條一條生成數據。
for i in cur:
print(i)
或者存儲需要的數據
l = (i[0] for i in cur)
# 數據量不大時也可以用列表生成式l = [i[0] for i in cur]
即使只select
一種數據帅韧,出現的結果也是元組里初,類似于(1,)
,而一般需要的數據只是元組里的這個1
忽舟,若使用
l = (i for i in cur)
由于沒有解包元組双妨,得不到想要的結果。
生成器的介紹還是看官方文檔比較好叮阅。
類似于
def func():
for i in range(3):
print(i)
func() # 0, 1, 2
要改寫成生成器刁品,只需要把print()
變成yield
,這個函數本身就可以循環(huán)了浩姥。
def func():
for i in range(3):
yield i
for i in func():
print(i) # 0, 1, 2
生成器只能循環(huán)一次挑随。之后再度對它循環(huán)不會生成值。
cur.execute(sql)
l = (i[0] for i in cur)
r = (i[1] for i in cur)
盡管r
不生成任何值勒叠,但上面這段代碼不會報錯兜挨。
如果是這樣
cur.execute(sql)
l = [i[0] for i in cur]
r = [i[1] for i in cur]
調試時會發(fā)現r
是一個空列表膏孟。
實際上要達成目的應該老老實實的這樣寫
cur.execute(sql)
l, r = [], []
for i in cur:
l.append(i[0])
r.append(i[1])
由于cur
本身就是一個生成器,實在不想用上面的寫法的話拌汇,就在for循環(huán)里直接處理i[1]
這樣的數據吧柒桑。
相對于list而言,生成器沒有長度的概念噪舀,無法使用len()
判斷長度幕垦,因此也不能判空。
def func():
for i in range(0):
yield i
if func():
print(1) # 1
l = (i for i in range(0))
if l:
print(1) # 1
因此傅联,在執(zhí)行一條select
語句后先改,想知道實際有沒有結果,不能用以下方式判斷
cur.execute(sql)
if cur:
for i in cur:
pass
為了寫入csv等蒸走,需要完整對齊的數據的話仇奶,可以這樣
cur.execute(sql)
for i in cur:
if i:
l.append(i)
break
else:
l.append('')
很奇怪的for...else...
語法,感覺自己在瞎寫了比驻,應該有其他方式來實現该溯,而不是非要用這種邏輯。不過别惦,能抓到老鼠就是好貓狈茉。
要插入幾十萬以上數據想節(jié)省時間的話,可以這樣
# datas是一個list掸掸,里面又包含幾十萬個list
bigN = 50000 # 一次插5萬條氯庆,設置的太高mysql也不讓插那么多
for i in range(len(datas)//bigN):
l, r = i * bigN, (i + 1) * bigN
sql = "insert ... values %s"
sql = sql % ','.join(datas[l:r])
cur.execute(sql)
if r + bigN > len(datas):
sql = "insert ... values %s"
sql = sql % ','.join(datas[r:]) # 邊界條件,保證尾部元素都能插入
cur.execute(sql)
不過以上代碼沒有檢查datas
長度小于bigN
的情況扰付,這個時候由于len(datas)//bigN
為0堤撵,是不會進行循環(huán)的,這點也要注意羽莺。