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

Python脚本读取DB中BLOB存储的CSV转DataFrame列名异常,Jupyter正常

问题描述

我有一张数据库表,包含8列:1列存储id,另外7列以BLOB二进制格式存储经过pickle序列化的CSV数据。读取这些数据并反序列化后,将每列数据存入单独的Pandas DataFrame中。

使用的代码如下:

engine = create_engine('sqlite:///test.db')
metadata_obj = MetaData()
metadata_obj.reflect(bind=engine)
Tabla1 = Table('Tabla1', metadata_obj, autoload_with=engine)
Session = sessionmaker(bind=engine)
session = Session()

query1= session.query(Tabla1).filter_by(idCliente=2).all()

for i in query1:

    df1=pd.DataFrame(pickle.loads(i.df1))
    df2=pd.DataFrame(pickle.loads(i.df2))
    df3=pd.DataFrame(pickle.loads(i.df3))
    df4=pd.DataFrame(pickle.loads(i.df4))
    df5=pd.DataFrame(pickle.loads(i.df5))
    df6=pd.DataFrame(pickle.loads(i.df6))
    df7=pd.DataFrame(pickle.loads(i.df7))
    
    df_list = [df1, df2, df3, df4, df5, df6, df7]
    df_names = ['df1', 'df2', 'df3', 'df4', 'df5', 'df6', 'df7']
    
    df_dict = dict(zip(df_names, df_list))

print(df1.columns)

在Jupyter Notebook中执行这段代码时,能正确获取DataFrame的列名;但在CMD中通过python main.py执行脚本时,却将数据的第一行当作列名,无法得到正确结果。

已确认Jupyter Notebook和脚本的依赖版本完全一致:

pandas 2.1.0
sqlalchemy 2.0.21
python 3.9.13
pickle 4.0
解决方案

1. 确认序列化时的DataFrame完整性

问题核心大概率是序列化时没有完整保存DataFrame的列信息。Jupyter和脚本环境的隐性差异可能导致序列化的对象结构不同——比如在某些场景下,序列化的是DataFrame的底层数据(如二维列表)而非完整的DataFrame对象。

重新序列化数据时,直接保存完整的DataFrame对象:

import pickle
import pandas as pd
from sqlalchemy import create_engine, Table, MetaData

# 读取原始CSV并转为DataFrame
df = pd.read_csv('your_source.csv')
# 序列化完整的DataFrame
serialized_df = pickle.dumps(df)

# 将序列化后的数据存入数据库
engine = create_engine('sqlite:///test.db')
metadata_obj = MetaData()
metadata_obj.reflect(bind=engine)
Tabla1 = Table('Tabla1', metadata_obj, autoload_with=engine)

with engine.connect() as conn:
    conn.execute(Tabla1.update().where(Tabla1.c.idCliente == 2).values(df1=serialized_df))
    conn.commit()

2. 反序列化时强制指定列名

如果无法重新序列化数据,可从Jupyter中导出正确的列名列表,在脚本中手动指定:

# 从Jupyter中获取正确列名后填入
correct_columns = ['列名1', '列名2', '列名3']  # 替换为实际列名

for i in query1:
    # 反序列化后重置列名
    df1_data = pickle.loads(i.df1)
    df1 = pd.DataFrame(df1_data, columns=correct_columns)
    # 其他df同理处理

3. 检查反序列化后的对象类型

在脚本中添加调试代码,确认反序列化后的对象类型:

loaded_data = pickle.loads(i.df1)
print(f"反序列化对象类型: {type(loaded_data)}")
print(f"数据前5行: {loaded_data[:5]}")

如果输出是二维列表/数组而非DataFrame,说明序列化时仅保存了数据,未保存列信息,必须重新序列化完整的DataFrame对象。

4. 统一工作目录

CMD执行脚本时的工作目录可能与Jupyter不同,导致隐性配置差异。在脚本开头添加工作目录检查与切换:

import os
# 切换到Jupyter的工作目录(替换为实际路径)
os.chdir("C:/your/jupyter/work/dir")
print(f"当前工作目录: {os.getcwd()}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:13:20