with engine.begin()和 with engine.connect()使用心得

以下内容完全是一个数据库小白的经验之谈,可能不太准确,见谅!

最近两天试图在树莓派上部署一个web应用,具体目标就是将接收到的数据转存到数据库中,一个是本地的kudu数据库,另一个是mysql数据库

# 如kudu库
impala.create_update_data('main', kudu_engine, df_main, 'main')
impala.create_update_data('child', kudu_engine, df_child, 'child')
impala.create_update_data('info', kudu_engine, df_info, 'info')
# 如mysql库
mysql.create_update_data('main', mysql_engine, df_main, 'main')
mysql.create_update_data('child', mysql_engine, df_child, 'child')
mysql.create_update_data('info', mysql_engine, df_info, 'info')
# impala
with engine.begin() as conn:
	conn.execute("UPSERT INTO {} ({}) VALUES ({})".format(table, keys, values))
# mysql
with engine.begin() as conn:
    conn.execute("REPLACE INTO {} ({}) VALUES ({})".format(table, keys, values))

但发现一个令人抓狂的问题:在本地x86机器上完全没问题,相同代码在树莓派上就完全看运气了(某些请求能正常入库,而大部分无法入库,而且没有任何异常)

最开始怀疑是因为机器性能导致,但尝试把导入kudu库的功能去掉后,发现入mysql库没有问题,所以是导入kudu库的代码问题。

将impala的‘with engine.begin() as conn:’换成:

conn = engine.connect()
conn.execute("UPSERT INTO {} ({}) VALUES ({})".format(table, keys, values))
conn.close()

发现一切又恢复正常了

看来是‘with engine.begin() as conn:’这条语句导致的

查了一下,上面这条语句好像是为了使用事物,但什么是事物,还需要进一步学习,最终把所有的‘with engine.begin() as conn:’改成‘with engine.connect() as conn:’,正常了!

总而言之,这里总结出的经验就是别用with engine.begin() as conn

参考:https://docs.sqlalchemy.org/en/13/core/connections.html


2020-04-30更新

在进行上面的修改后,又发现问题:树莓派中使用impala engine的df.to_sql(table, engine, if_exists=‘append’)会出问题,而mysql engine的貌似没有问题,所以索性把所有df.to_sql全部进行替换

dic = df.to_dict('records')
keys = ', '.join(
    key for key, value in dic[0].items()
)
values = ''
for item in dic:
    value = '(' + ', '.join(
    "'{}'".format(value) \
    if type(value) == str else "{}".format(value) \
    for key, value in item.items()
    ) + ')'
    values = (values + ',' + value).strip(',')
with engine.connect() as conn:
    conn.execute("INSERT INTO {} ({}) VALUES ({})".format(table, keys, values))
import pandas as pd from sqlalchemy import create_engine # 连接到数据库 engine = create_engine('mysql+pymysql://user:password@localhost/database') # 获取所有表格的名称 with engine.connect() as conn, conn.begin(): tables = conn.execute("SHOW TABLES").fetchall() # 遍历所有表格 for table in tables: table_name = table[0] table_name_quoted = '' + table_name + '' # 检查是否存在名为'a'的列,如果不存在则添加'a'和'b'列 with engine.connect() as conn, conn.begin(): a_column = conn.execute("SHOW COLUMNS FROM " + table_name_quoted + " LIKE 'a'").fetchone() if a_column is None: conn.execute("ALTER TABLE " + table_name_quoted + " ADD COLUMN a DECIMAL(10,2)") conn.execute("ALTER TABLE " + table_name_quoted + " ADD COLUMN b DECIMAL(10,2)") # 查询net_mf_amount列的数据 query = "SELECT trade_date, net_mf_amount FROM " + table_name_quoted + " ORDER BY trade_date DESC" df = pd.read_sql_query(query, engine) # 计算a和b列 a_column = [] b_column = [] for i in range(len(df)): if i == 0: a_column.append(None) b_column.append(None) else: if pd.notnull(df.iloc[i]['net_mf_amount']) and pd.notnull(df.iloc[i-1]['net_mf_amount']): if i-2 >= 0: if pd.notnull(df.iloc[i-2]['net_mf_amount']): a = df.iloc[i]['net_mf_amount'] - df.iloc[i-1]['net_mf_amount'] b = df.iloc[i]['net_mf_amount'] - df.iloc[i-2]['net_mf_amount'] a_column.append(a) b_column.append(b) else: j = i-3 while j >= 0: if pd.notnull(df.iloc[j]['net_mf_amount']): a = df.iloc[i]['net_mf_amount'] - df.iloc[i-1]['net_mf_amount'] b = df.iloc[i]['net_mf_amount'] - df.iloc[j]['net_mf_amount'] a_column.append(a) b_column.append(b) break j -= 1 else: a = df.iloc[i]['net_mf_amount'] - df.iloc[i-1]['net_mf_amount'] b = None a_column.append(a) b_column.append(b) else: a_column.append(None) b_column.append(None) # 将结果保存到数据库 with engine.connect() as conn, conn.begin(): for i in range(len(df)): conn.execute("UPDATE " + table_name_quoted + " SET a=%s, b=%s WHERE trade_date=%s", (a_column[i], b_column[i], df.iloc[i]['trade_date'])) # 关闭连接 engine.dispose() 有5000个表格,使用多线程,线程池
05-27
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值