最祥解决python 将Dataframe格式数据上传数据库所碰到的问题

news2025/6/23 16:53:16

碰到的问题

上传Datafrane格式的数据到数据库 会碰见很多错误 举几个很普遍遇到的问题(主要以SqlServer举例)

这里解释下 将截断字符串或二进制数据 这个是字符长度超过数据库设置的长度

然后还有字符转int失败 或者字符串转换日期/或时间失败 这个是碰到的需要解决的最多的问题 当然仅代表个人意见和碰到的数据而言

先来看看使用pands进行上传数据库

import pandas as pd
from sqlalchemy import create_engine


# 连接数据库
# 因为本机是使用windows进行验证登录数据库 所以不需要用户和密码
data = pd.read_excel('test.xlsx')
conn = create_engine('mssql+pymssql://服务器名/数据库名')
# name为表名 dtype={} 如果数据库中未存在表 所有nvarchar将自动设置为max nvarchar(MAX)
data.to_sql(name='tablename', if_exists='append', con=conn, schema="dbo",index=False, dtype={})
conn.dispose()

我们先看看如果数据存在以上出现的错误报错情况

不能将所有错误展现出来 只会报第一次出现的错误 字符串长度过长的错误

这个就是我所构建的数据 作为参照给大家看看

接下来看下其他的链接方式所报错

按照insert语句插入 这里说名下因为连接方式不一样 分为pymssql 和 pyodbc链接方式

第一种pyodbc方式连接数据库
第一种:一次性全部插入数据相当于我们的insert table values(),()
import pyodbc
import pandas as pd


# 使用pyodbc链接数据库并进行上传
data = pd.read_excel('test.xlsx')
conn = pyodbc.connect(
    r'Driver={SQL Server};Server=服务器名;Database=数据库名;Trusted_Connections=yes;')
cursor = conn.cursor()
value = (tuple(i) for i in data.values)
sqlstr = "insert into {} values ({})".format('tablename',' ,'.join(['?']*len(data.columns)))
try:
    a = cursor.executemany(sqlstr, value)
    conn.commit()
except Exception as e:
    print(e)
    conn.rollback()
finally:
    conn.close()

报错

还是只会报一种错误

第二种一行一行插入

import pandas as pd
import pyodbc


data = pd.read_excel('test.xlsx')
columns_ = ', '.join(data.columns)
conn = pyodbc.connect(
    r'Driver={SQL Server};Server=服务器名;Database=数据库名;Trusted_Connections=yes;')
cursor = conn.cursor()
# 众所周知 sqlserver inser插入对于文本数据是需要''单引号引用起来所以 我们直接读取出来的数据不可以直接使用会出错 默认为 insert tablename value (1, Jonny, None, 1, 2024-04-01) 所以会出错 
# 转变形式
# 将data 进行变换
for _, row in data.iterrows():
    data_item = [f"\'{row[column]}\'" for column in list(data.columns)]
    sqlstr = f'''INSERT INTO tablename ({columns_}) values ({", ".join(data_item)})'''
# 注意上面','后面有一个空格 符合Sql插入的写法
try:
    cursor.execute(sqlstr)
except pyodbc.Error as e:
    print(e)
finally:
    conn.close()

报错状况

 

可以清楚的看到 将所有的错误都显示了出来

 第二种使用pymssql进行链接数据库

import pymssql
import pandas as pd

data = pd.read_excel('test.xlsx')

conn = create_engine(r'mssql+pymssql://服务器名/数据库名')
for _, row in data.iterrows():
    data_item = [f"\'{row[column]}\'" for column in list(data.columns)]
    sqlstr = f'''INSERT INTO test ({columns_}) VALUES ({", ".join(data_item)})'''
    try:
        cursor.execute(sqlstr)
    except pymssql.Error as e:
        print(e)

报错情况 这里需要说明下 except pymssql.Error 和 pyodbc.Error不一样

 

以上为两种不同连接方式的不同报错状况 

接下来是经过特殊处理查找具体报错在哪一行哪一列

数据库表属性查看

以pyodbc的报错作为主要展示  可以看到字符串长度过长报错是22001代码

这里需要说一下 获取数据库字段详细设置的代码

# 获取数据库表中的配置 包含列名、类型、nvarchar()或varchar()最大长度
import pyodbc

conn = pyodbc.connect(r'Driver={SQL Server};Server=服务器名;Database=数据库名;Trusted_Connection=yes;')
cursor = conn.cursor()
sqlstr = '''select column_name, data_type, character_maximum_length FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '表名' '''
try:
    a = cursor.execute(sqlstr)
    col_attr = a.fetchall()
    conn.commit()
except Exception as e:
    print(e)
finally:
    conn.close()

这里需要说明下 不建议使用官方的那种获取表属性方法 展示一下

 

这里显示的最大长度设置为100 其实表格设置的是50  会进行扩大一倍 所以为了准确判断 我们字符串是否超出此列最大设置长度不建议使用 

具体报错查看

如果全部数据正确则上传 不正确则不上传并且指出具体错误到哪一行哪一列 行数是具体数据的哪一行 不是Excel的index

这里以最难的nvarchar长度举例  因为python库包装的底层代码原因 所以报错不是很清楚 查找难度会困难点

需要准备的工作

  1. 查找表属性
  2. 使用python和sqlserver上传数据
  3. 借用上传数据查找出错误具体内容以及具体位置

测试数据展示 

Sqlserver表属性展示

# 调用要使用的python库
# 这里建议pyodbc库 原因可查看<碰到的问题>
import pyodbc
import pandas as pd


# 读取数据
data = pd.read_excel(r'D\test2.xlsx')

# 获取数据库表属性
def get_the_sqltable_attr(tablename):
    conn = pyodbc.connect(r'Driver={SQL Server};Server=服务器名;Database=数据库名;Trusted_Connection=yes;')
    cursor = conn.cursor()
    sqlstr = f'''select column_name, data_type, character_maximum_length FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{tablename}' '''
    try:
        a = cursor.execute(sqlstr)
        tab_attr = a.fetchall()
        return tab_attr
        conn.commit()
    except Exception as e:
        print(e)
    finally:
        conn.close()
 
table_attr = get_the_sqltable_attr(tablename='test')
print(table_attr)

# 取读取进来的数据进行元组化, 符合insert语句中的(column1, column2)
columns_ = ', '.join(data.columns)
print(columns_)

#连接数据库 准备上传
conn = pyodbc.connect(r'Driver={SQL Server};Server=服务器名;Database=数据库名;Trusted_Connection=yes;')
cursor = conn.cursor()
# 循环行 一行一行插入数据 速度会比to_sql慢 但是可以具体反应错误 碰到的问题有详解
for _, row in data.iterrows():
    # 插入的值也要进行变换 后面我会输出 可让观察不处理的报错情况
    data_item = data_item = [f"\'{row[column]}\'" for column in list(data.columns)]
    sqlstr = f''' INSERT INTO 表名 ({columns_} VALUES ({', '.join(data_item)}))'''
    try:
        cursor.execute(sqlstr)
    except pyodbc.Error as e:
        if e.args[0] = '22001':
            s = get_the_sqltable_attr(tablename='test')
            # 因为上面的特殊处理 所以取出来的时候也会麻烦点
            # 查出报错
            trouble = [[s.index(i), i[0], i[2], i[1]] for i in s]
            data_new = [i.split("'")[1] for i in data_item]
            for i in range(len(data_new)):
                if trouble[i][3] == 'nvarchar' and len(data_new[i]) > trouble[i][2] or trouble[i][3] == 'varchar' and len(data_new[i]) > trouble[i][2]:
                row = int(data_item[0].split("'")[1])
                column = trouble[i][1]
                charter = data_new[i]
                print(f'第{row}行, {column}列, 字符: {charter}字符串过长')

 

 现在说明下上述注释掉的为什么要将data的value进行特殊处理 {data_item = [f"\'{row[column]}\'" for column in list(data.columns)]}

如果不进行特殊处理 我们拿出来的值是

这样 insert table的value(直接传入列表)对于Sqlserver语言来说 为错

有些人可能会说直接转换为tuple()  博主亲测错误,如果为元组 里面的字符串会不带' ',但是sqlserver是需要字符串带' '

时间类型的也可以像如上处理方式一样,类型转换错误会简单点  有其他任何方法 欢迎和博主讨论 都湿手打的 如果错误了 感谢提出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1584534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

比特币减半后 牛市爆发

作者&#xff1a;Arthur Hayes of Co-Founder of 100x 编译&#xff1a;Qin jin of ccvalue (以下内容仅代表作者个人观点&#xff0c;不应作为投资决策依据&#xff0c;也不应被视为参与投资交易的建议或意见&#xff09;。 Ping PingPing&#xff0c;我的手机发出的声音&…

词频统计程序

使用Hadoop MapReduce处理文本文件&#xff0c;Mapper负责将文本分割为单词&#xff0c;然后Reducer对每个单词进行计数&#xff0c;最后将结果写入输出文件。 // 定义WordCount公共类 public class WordCount {// 主入口方法&#xff0c;处理命令行参数public static void m…

C语言进阶|顺序表

✈顺序表的概念及结构 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串.. 线性表在逻辑上是线性结构&#xff0c;也就说是连…

推荐学习什么编程语言?

选择编程语言学习时&#xff0c;除了就业因素外&#xff0c;还可以考虑以下几个方面来决定学习哪些编程语言&#xff1a; 个人兴趣与目标&#xff1a;如果你对某个特定领域感兴趣&#xff0c;比如游戏开发、数据分析、人工智能等&#xff0c;可以选择与该领域紧密相关的编程语言…

Python---【re库的使用】

目录&#xff1a; 一.re库简介 二.match方法 三.Match对象方法 四.使用search()方法进行匹配 五.使用findall()方法进行匹配 六.使用sub()方法替换字符串 七.使用split()方法分割字符串 一.re库简介 re库是Python用来实现“正则表达式”的库&#xff0c;并且re库在Pyth…

使用 nginx 服务器部署Vue项目

安装nginx 文本代理服务器 centos下载 注意需要root权限 在CentOS服务器上下载Nginx可以通过以下步骤完成&#xff1a; 更新系统软件包列表&#xff1a; yum update 安装EPEL存储库&#xff08;Extra Packages for Enterprise Linux&#xff09;&#xff1a; yum install…

分类预测 | Matlab实现KPCA-IDBO-LSSVM基于核主成分分析和改进蜣螂优化算法优化最小二乘支持向量机分类预测

分类预测 | Matlab实现KPCA-IDBO-LSSVM基于核主成分分析和改进蜣螂优化算法优化最小二乘支持向量机分类预测 目录 分类预测 | Matlab实现KPCA-IDBO-LSSVM基于核主成分分析和改进蜣螂优化算法优化最小二乘支持向量机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述…

Visual Studio C++ 正确创建项目与更改文件名

1、创建项目 1&#xff09;打开Visual Studio&#xff0c;选择创建新项目。 2&#xff09;创建空项目 3&#xff09;配置新项目&#xff0c;注意不要勾选 " 将解决方案和项目放在同一目录中 " 。并将位置的文件夹设为与解决方案同名&#xff0c;方便管理。项目名称则…

《零秒思考》像麦肯锡精英一样思考 - 三余书屋 3ysw.net

零秒思考&#xff1a;像麦肯锡精英一样思考 大家好&#xff0c;今天我们要深入探讨的著作是《零秒思考》。在领导提出问题时&#xff0c;我们常常会陷入沉思&#xff0c;却依然难以有所进展&#xff0c;仿佛原地踏步&#xff0c;但是身边的同事却能够立即给出清晰的回答。这种…

乡村智慧化升级:数字乡村打造农村生活新品质

目录 一、乡村智慧化升级的内涵与意义 二、乡村智慧化升级的具体实践 1、加强农村信息基础设施建设 2、推广智慧农业应用 3、提升乡村治理智慧化水平 4、丰富智慧乡村生活内容 三、数字乡村打造农村生活新品质的成果展现 1、农业生产效率与质量双提升 2、农民收入与消…

学习Rust的第二天:Cargo

We dive into Cargo, the powerful and convenient build system and package manager for Rust. 基于Steve Klabnik的《The Rust Programming Language》一书&#xff0c;我们深入了解Cargo&#xff0c;这是Rust强大而方便的构建系统和包管理器。 Cargo is a robust and effic…

Linux文件与目录的默认权限和隐藏权限

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、Linux的起源与发展 二、文件默认权限&#xf…

vitepress/vite vue3 怎么实现vue模版字符串实时编译

如果是vue模版字符串的话&#xff0c;先解析成模版对象 另一篇文章里有vue模版字符串解析成vue模版对象-CSDN博客 //vue3写法&#xff08;vue2可以用new Vue.extend(vue模版对象)来实现&#xff09;import { createApp, defineComponent } from vue;// 定义一个简单的Vue组件c…

【从浅学到熟知Linux】进程状态与进程优先级(含进程R/S/T/t/D/X/Z状态介绍、僵尸进程、孤儿进程、使用top及renice调整进程优先级)

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程及数据库等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 进程状态进程状态查看R运行状态&#xff08;running&#xff09;S睡眠状态&#xff08;sleeping&a…

软考 系统架构设计师系列知识点之大数据设计理论与实践(2)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之大数据设计理论与实践&#xff08;1&#xff09; 所属章节&#xff1a; 第19章. 大数据架构设计理论与实践 第1节 传统数据处理系统存在的问题 最严重的问题是系统并没有对认为错误进行工程设计&#xff0c;仅靠备份是…

[C++]让C++的opencv库支持写出h264格式视频

当我们写下面测试代码时候&#xff1a; #include <opencv2/opencv.hpp>int main() {cv::VideoCapture cap("E:\\car.mp4"); // 打开默认摄像头if (!cap.isOpened()) {std::cout << "读取完毕!" << std::endl;return -1;}double fps ca…

HarmonyOS时区和语言设置-使用相关api实现系统语言和地区设置

介绍 本示例展示了i18n&#xff0c;intl&#xff0c;resourceManager在eTS中的使用&#xff0c;使用相关api实现系统语言和地区设置、时间和时区设置&#xff0c;展示了区域格式化示例。 效果预览 使用说明 1.启动应用&#xff0c;进入应用&#xff0c;首页分为三个按钮&…

Linux第87步_阻塞IO实验

阻塞IO是“应用程序”对“驱动设备”进行操作&#xff0c;若不能获取到设备资源&#xff0c;则阻塞IO应用程序的线程会被“挂起”&#xff0c;直到获取到设备资源为止。 “挂起”就是让线程进入休眠&#xff0c;将CPU的资源让出来。线程进入休眠后&#xff0c;当设备文件可以操…

nginx配置证书和私钥进行SSL通信验证

文章目录 一、背景1.1 秘钥和证书是两个东西吗&#xff1f;1.2 介绍下nginx配置文件中参数ssl_certificate和ssl_certificate_key1.3介绍下nginx支持的证书类型1.4 目前nginx支持哪种证书格式&#xff1f;1.5 nginx修改配置文件目前方式也会有所不同1.6 介绍下不通格式的证书哪…

Vue2.x实现商城购物车

1.实现购物车页面 在页面中显示购物车中的商品信息&#xff0c;并能进行数量增减及商品删除操作&#xff0c;购物车中金额也随商品数量的变化而变化 2.创建cart.html页面 创建cart.html页面&#xff0c;在其中创建Vue实例&#xff0c;实例中首先准备一些商品信息以供显示&a…