You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Pandas DataFrame更新到PostgreSQL多表的现有行(按列匹配)

PostgreSQL批量更新MACD数据方案

背景

数据库存在三个独立PostgreSQL表:AUDCAD、AUDJPY、AUDUSD,需将MACD相关NumPy数组数据更新到各表原有行的macd_480、macd_840、macd_1518、macd_2400列,而非新增行。原INSERT逻辑会生成空值行,UPDATE执行报错,以下提供psycopg2和SQLAlchemy两种解决方案。

数据示例

更新前表数据

row_no    O   H   L   C  macd_480  macd_840  macd_1518  macd_2400
0      1    10  20  30  40     None      None        None      None
1      2    10  20  30  40     None      None        None      None
2      3    10  20  30  40     None      None        None      None
3      4    10  20  30  40     None      None        None      None

INSERT后(不符合预期)

row_no     O     H     L     C  macd_480  macd_840  macd_1518  macd_2400
0       1     10    20    30    40     None      None       None       None
1       2     10    20    30    40     None      None       None       None
2       3     10    20    30    40     None      None       None       None
3       4     10    20    30    40     None      None       None       None
4       5   None  None  None  None       50        60         70         80
5       6   None  None  None  None       50        60         70         80
6       7   None  None  None  None       50        60         70         80
7       8   None  None  None  None       50        60         70         80

预期结果

row_no   O   H   L   C  macd_480  macd_840  macd_1518  macd_2400
0       1   10  20  30  40       50        60         70         80
1       2   10  20  30  40       50        60         70         80
2       3   10  20  30  40       50        60         70         80
3       4   10  20  30  40       50        60         70         80

方案一:psycopg2批量更新

核心是利用PostgreSQL的UPDATE...FROM语法,将MACD数据与表中row_no关联,批量匹配更新,避免单条更新效率低下。

import pandas as pd
import numpy as np
import psycopg2
from psycopg2 import extras

# 数据库连接信息,替换为你的实际配置
DB_CONFIG = {
    "dbname": "your_db",
    "user": "your_user",
    "password": "your_pwd",
    "host": "your_host"
}

SYMBOLS = ['AUDCAD', 'AUDJPY', 'AUDUSD']

# 生成带row_no的数据集(row_no与表中现有行一一对应)
def prepare_update_data(macd_480, macd_840, macd_1518, macd_2400):
    macd_df = pd.DataFrame(
        np.column_stack((macd_480, macd_840, macd_1518, macd_2400)),
        columns=['macd_480', 'macd_840', 'macd_1518', 'macd_2400']
    ).drop(index=0)
    # 匹配表中row_no(drop(index=0)后索引为1-4,对应表中row_no 1-4)
    macd_df['row_no'] = macd_df.index
    return macd_df[['row_no', 'macd_480', 'macd_840', 'macd_1518', 'macd_2400']].values.tolist()

# 批量更新SQL模板
UPDATE_QUERY = """
UPDATE {table}
SET macd_480 = data.macd_480,
    macd_840 = data.macd_840,
    macd_1518 = data.macd_1518,
    macd_2400 = data.macd_2400
FROM (VALUES %s) AS data(row_no, macd_480, macd_840, macd_1518, macd_2400)
WHERE {table}.row_no = data.row_no;
"""

# 执行更新
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()

for symbol in SYMBOLS:
    # 替换为当前symbol对应的MACD数组
    update_data = prepare_update_data(macd_480, macd_840, macd_1518, macd_2400)
    query = UPDATE_QUERY.format(table=symbol)
    extras.execute_values(
        cursor,
        query,
        update_data,
        template="(%s, %s, %s, %s, %s)",
        page_size=1000
    )

conn.commit()
cursor.close()
conn.close()

方案二:SQLAlchemy批量更新

利用SQLAlchemy的bulk_update_mappings方法,结合Pandas处理数据,代码更简洁,无需手写复杂SQL。

from sqlalchemy import create_engine, Table, MetaData
import pandas as pd
import numpy as np

# 数据库连接字符串,替换为你的实际配置
DB_URL = "postgresql://your_user:your_pwd@your_host:5432/your_db"
engine = create_engine(DB_URL)
metadata = MetaData()

SYMBOLS = ['AUDCAD', 'AUDJPY', 'AUDUSD']

# 生成用于批量更新的字典列表
def prepare_update_mappings(macd_480, macd_840, macd_1518, macd_2400):
    macd_df = pd.DataFrame(
        np.column_stack((macd_480, macd_840, macd_1518, macd_2400)),
        columns=['macd_480', 'macd_840', 'macd_1518', 'macd_2400']
    ).drop(index=0)
    macd_df['row_no'] = macd_df.index
    return macd_df.to_dict('records')

# 执行批量更新
with engine.begin() as conn:
    for symbol in SYMBOLS:
        # 加载表结构
        table = Table(symbol, metadata, autoload_with=engine)
        # 替换为当前symbol对应的MACD数组
        update_mappings = prepare_update_mappings(macd_480, macd_840, macd_1518, macd_2400)
        # 批量更新
        conn.bulk_update_mappings(table, update_mappings)

内容的提问来源于stack exchange,提问作者rn kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:35:56