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

碰到的问题

上传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 pyodbcdata = 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 pddata = 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 pyodbcconn = 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_attrconn.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.mzph.cn/news/806485.shtml

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

相关文章

Java面试题戏剧

目录 第一幕 、第一场&#xff09;某大厦楼下大门前第二场&#xff09;电梯中第三场&#xff09;走廊中 第二幕、第一场&#xff09;公司前台第二场&#xff09;公司卫生间 第三幕、第一场&#xff09;一场异常面试 第四幕 、第一场&#xff09;大厦楼下门口第二场&#xff09;…

Lobe UI - 基于 AntDesign 开发的 AIGC Web 应用的开源 UI 组件库

今天推荐一个可以快速开发 ChatGPT UI 界面的组件库&#xff0c;质量很高&#xff0c;拿来就能用。 Lobe UI 是由 lobehub 团队开发的一套 web UI 组件库&#xff0c;和我之前推荐的很多通用型的 UI 组件库不同&#xff0c;Lobe UI 是专门为目前火热的 AIGC 应用开发而打造&am…

Objective-C学习笔记(内存管理、property参数)4.9

1.引用计数器retainCount&#xff1a;每个对象都有这个属性&#xff0c;默认值为1&#xff0c;记录当前对象有多少人用。 为对象发送一条retain/release消息&#xff0c;对象的引用计数器加/减1&#xff0c;为对象发一条retainCount,得到对象的引用计数器值&#xff0c;当计数器…

上海计算机学会 2023年6月月赛 乙组T3 工作安排(结构体排序、贪心算法)

第三题&#xff1a;T3工作安排 标签&#xff1a;结构体排序、贪心算法 题意&#xff1a;有 n n n份任务。完成第 i i i份任务需要 t i t_i ti​的时间&#xff0c;在这份任务没有完成之前&#xff0c;每一个单位时间会收到 f i f_i fi​单位的罚款。求以什么顺序安排这些任务&…

鸿蒙实战开发-如何实现选择并查看文档与媒体文件

介绍 应用使用ohos.file.picker、ohos.multimedia.mediaLibrary、ohos.file.fs 等接口&#xff0c;实现了picker拉起文档编辑保存、拉起系统相册图片查看、拉起视频并播放的功能。 效果预览 使用说明&#xff1a; 在首页&#xff0c;应用展示出最近打开过的文档信息&#xf…

【AcWing】蓝桥杯集训每日一题Day22|区间DP|博弈论|1388.游戏(C++)

1388.游戏 1388. 游戏 - AcWing题库难度&#xff1a;中等时/空限制&#xff1a;1s / 64MB总通过数&#xff1a;1429总尝试数&#xff1a;1925来源&#xff1a;usaco training 3.3算法标签博弈论DP区间DP 题目内容 玩家一和玩家二共同玩一个小游戏。 给定一个包含 N 个正整数的…

【MATLAB 分类算法教程】_3麻雀搜索算法优化支持向量机SVM分类 - 教程和对应MATLAB代码

分类代码案例3:麻雀搜索算法优化支持向量机SVM分类 - MATLAB完全代码教程 1. 初始化代码2.读取数据代码3.数据预处理代码4.利用麻雀搜索算法SSA求解最佳的SVM参数c和g代码5.根据最佳的参数进行SVM模型训练代码6.SVM模型预测代码7.准确率分析以及分类结果对比作图代码本文以红酒…

Python中的生成器与迭代器:概念、区别及其实用性解析

Python中的生成器与迭代器&#xff1a;概念、区别及其实用性解析 在Python编程中&#xff0c;生成器&#xff08;Generators&#xff09;和迭代器&#xff08;Iterators&#xff09;是处理序列数据的两个重要概念。它们为处理大量数据或复杂数据结构提供了高效且灵活的方式。本…

SpringCloudAlibaba-整合sentinel(四)

目录地址&#xff1a; SpringCloudAlibaba整合-CSDN博客 这里只关注代码部分&#xff0c;至于sentinel服务UI的实用&#xff0c;后面可以补上 这里做一个改造&#xff1a; 因为sentinel可以和openfeign结合使用&#xff0c;为微服务做熔断降级&#xff1b; 为了方便微服务之间…

马云最新发声:AI时代刚刚到来,一切才刚开始,我们正当其时!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

3. Spring 注解存储对象 Bean的命名规范

从Java5.0开始&#xff0c;Java开始支持注解。Spring做为Java生态中的领军框架&#xff0c;从2.5版本后也开始支持注解。相比起之前使用xml来配置Spring框架&#xff0c;使用注解提供了更多的控制Spring框架的方式。 SpringFramework版本对应jdk版本重要特性SpringFramework 1…

Unity之Unity面试题(五)

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之Unity面试题&#xff08;五&#xff09; TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取…

《Linux运维实战:Kylin V10操作系统开启安装软件保留缓存设置》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;Linux运维实战总结 一、操作步骤 1、改系统/etc/yum.conf配置文件&#xff0c;开启安装软件保留缓存设置 [rootecs-90c2-0003 ~]# vim /etc/yum.…

Ticket Servers: Distributed Unique Primary Keys on the Cheap(经济高效的分布式ID生成方案) 翻译

本文是对Ticket Servers: Distributed Unique Primary Keys on the Cheap https://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/ 的翻译&#xff0c;此文主要讲述了flicker公司的用于生成分布式ID的Ticker Servers 的背景、原理、…

爬虫逆向实战(40)-某江酒店登陆(AES、MD5)

一、数据接口分析 主页地址&#xff1a;某江酒店 1、抓包 通过抓包可以发现数据接口是/api/member/login 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现&#xff0c;有TDFingerprint、blackBoxMd5、password和sw四个加密参数&#x…

Android自定义控件ScrollView实现上下滑动功能

本文实例为大家分享了Android ScrollView实现上下滑动功能的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 package com.example.zhuang; import android.content.Context; import android.util.AttributeSet; import android.util.DisplayMetrics; import android…

Python---Numpy酒鬼漫步

import numpy as np# 模拟随机游走过程&#xff0c;返回每一步的结果&#xff08;0或1&#xff09; def random_walks(steps):draws np.random.randint(0, 2, sizesteps)return draws# 根据随机游走的结果计算每一步的方向步长&#xff0c;返回方向数组&#xff08;1或-1&…

HTML5学习记录

简介 超文本标记语言&#xff08;HyperText Markup Language&#xff0c;简称HTML&#xff09;&#xff0c;是一种用于创建网页的标准标记语言。 编辑器 下载传送门https://code.visualstudio.com/ 下载编辑器插件 标题 标题通过 <h1> - <h6> 标签进行定义。 …

科技助力输电线安全隐患预警,基于YOLOv5全系列参数【n/s/m/l/x】模型开发构建电力设备场景下输电线安全隐患目标检测预警系统

电力的普及让我们的生活变得更加便利&#xff0c;四通八达的电网连接着生活的方方面面&#xff0c;电力能源主要是依托于庞大复杂的电网电力设备进行传输的&#xff0c;有效地保障电网场景下输电线的安全对于保障我们日常生活所需要的电力有着重要的意义&#xff0c;但是电力设…