调用外部脚本数据库对象执行SQL INSERT语句失败排查
问题分析与解决:PostgreSQL插入DataFrame时的%s语法错误
核心问题
你的MyDatabase类中query_func方法存在参数传递遗漏:方法定义了params参数,但调用self.cur.execute()时没有将该参数传入。
当你直接调用cur.execute(scores_bets_table_insert, list(row))时,psycopg2会将%s识别为参数占位符,自动完成替换逻辑;但调用query_func时,由于没有传递params,psycopg2会把SQL语句中的%s当作PostgreSQL原生语法处理,而PostgreSQL不支持%s占位符,因此抛出语法错误。
修复代码
修改database_config脚本中的query_func方法,将params参数传递给execute:
import os import psycopg2 # password for the database from an environment variable db_pw = os.environ.get('DB_PASS') conn_str = "host=localhost user=postgres dbname=nfl_scores_bets password={}".format(db_pw) class MyDatabase(): def __init__(self): self.conn = psycopg2.connect(conn_str) self.cur = self.conn.cursor() self.conn.set_session(autocommit=True) def query_func(self, query, params=None): try: # 关键修复:传入params参数 self.cur.execute(query, params) except psycopg2.Error as e: print(e)
性能优化建议
用iterrows()逐行插入效率极低,推荐以下两种批量插入方案:
- 使用
psycopg2.extras.execute_batch批量执行:
from psycopg2.extras import execute_batch db = MyDatabase() # 将DataFrame转为列表格式批量传入 execute_batch(db.cur, scores_bets_table_insert, scores_bets.values.tolist())
- 使用pandas自带的
to_sql方法(需依赖SQLAlchemy):
from sqlalchemy import create_engine # 创建数据库连接引擎 engine = create_engine(f'postgresql://postgres:{db_pw}@localhost/nfl_scores_bets') # 批量插入DataFrame,if_exists='append'表示追加数据 scores_bets.to_sql('scores_bets', engine, if_exists='append', index=False)
内容的提问来源于stack exchange,提问作者DataSwell
相关产品推荐
相关产品推荐

