error:not all arguments converted during string formatting 解决

2019-02-16 09:09:12   错误异常

error:not all arguments converted during string formatting


  • 先把解决办法奉上:传入单个参数的时候把param 换成 tuple :(param,) 或者换成list : [param]

  • 用python操作数据库的时候,使用MySQLdb遇到一个问题,是这样的:execute方法传入单个参数,一直报错not all arguments converted during string formatting
    
    with DBHelper as db:
    pid = 10010
    db.fetch_tuple_as_list("SELECT `name` FROM `vien_table` WHERE `id` = %s LIMIT 1", pid)

with DBHelper as db: names = [(a),(b),(c)] db.update_batch("INSERT INTO vien_table(name) VALUES(%s)", names)

- DBHelper的两个方法fetch_tuple_as_list、update_batch:

def fetch_dict_as_list(self, sql, params = None): if not self._dcursor: self._dcursor = self.get_cursor(MySQLdb.cursors.DictCursor) try: self._dcursor.execute(sql, params) self._current_cursor = self._dcursor res = self._dcursor.fetchall() if res: return list(res) except Exception as e: print self.get_time(),'Unable to get results !',e return None

def update_batch(self,sql,items,stepsize = 1000): if not self._tcursor: self._tcursor = self.get_cursor() try: size = int(stepsize) length = len(items) size = size if length >= size else length print size for i in xrange(0, (length + size - 1) / size): self._tcursor.executemany(sql,items[isize:(i+1)size]) self._current_cursor = self._tcursor if self._autocommit: self._conn.commit() return True except Exception as e: if self._autocommit: self._conn.rollback() print self.get_time(),'Unable to update !\n',e return False

> 可以看到,其实最后我调用的是MySQLdb的execute和executemany方法。而错误的位置就在这里,参数转换的时候没有执行成功。

MySQLdb/cursors.py line 187: query = query % tuple([db.literal(item) for item in args])

> 上述是源码,可以看到这里其实就是将所有传入参数遍历,然后对每一个item用literal处理,literal函数其实就是对item进行转义,然后在加上引号作为字符串以便MySQL识别。例如`str = "low's" , sql = ' SELECT * FROM table where name = %s ' % str` 这种情况下最后的sql是`SELECT * FROM table where name = low's ` 这样就会给MySQL造成困惑,而不能执行,最简单的方法就是给%s加上引号,像这样`"%s"` ,然后给str转义,像这样 `low\'s`。这样我们交给MySQL的就是`SELECT * FROM table where name = "low\'s"'`。而其实literal就是做了这样一件事,它会把low's变成'low\\\'s',之所以是 `\\` 是因为它先转`\` 然后交给MySQL的就是low\'s了,正好满足需求。

> 言归正传,由于execute是把你传入的参数当成一个Iterator来遍历了,如果你只是传入一个简单的参数,就会造成convert失败,所以如何解决呢?可能你现在就可以想到了,那我传入一个tuple。没错,这个是可以的,但是你会不会直接这样用呢`execute(sql,('vien'))`,如果是这样那你就错了,可以试一下输出`type(('vien'))`,你会发现结果不是`tuple`而是`string`!Python官方文档是这样解释的:如果tuple只有一个值,那么不会被当做是tuple,而是这个值的类型。所以你要用tuple怎么用呢,很简单,加个逗号:`('vien',)` 这样就会被当成是tuple了,当然你也可以将它变成list,list就简单多了,直接`['vien']` 就好了。所以我给这个DBHelper加了个方法,来处理这种情况:

def format_param(self,param,batch = False): if param: if batch: return [i if (isinstance(i,tuple) or isinstance(i,list)) else [i] for i in param] (isinstance(param,tuple) or isinstance(param,list)) and param or [param] return None



> 这样问题就解决了。
viencoding.com版权所有,允许转载,但转载请注明出处和原文链接: https://viencoding.com/article/60
欢迎小伙伴们在下方评论区留言 ~ O(∩_∩)O
文章对我有帮助, 点此请博主吃包辣条 ~ O(∩_∩)O

猜你喜欢


评论

There are no comments yet.
未登录

登录后即可发表评论

登录或注册

标签

AdSense Anaconda Android apache API apt Auth AWS B-tree Bandwagon Blog bower brew bytes Caffe Catalina certbot Charles cloudcone Composer conda CoreML CPU crontab CSS csv Cuda cv2 datetime Digitalocean DNS Docker Docker-Compose Eloquent Excel export Flask FTP GET Git GitHub GitLab Gmail GoDaddy Google GTM hash Homebrew Homestead HTML http HTTPS IDEA image imagemagick imagick imgick import InnoDB ios iou iPhone ISO8601 iTerm2 Java JavaScript JPG JS Keras Laravel Laravel-Admin lazyload Linux list Livewire lnmp load logs Lravel Mac Markdown matplotlib md5 mix MobileNet Mojave mongo MongoDB MySQL Namesilo Nginx Node npm numpy Nvidia Nvidia-Docker onevps OpenCV Openpose openpyxl oss Outline parse PayPal PHP php-fpm PhpStorm PHP扩展 PIL Pillow pip PNG POST Protobuf PyCharm pyenv pymongo Python Python,人工智能,机器学习,VOC,xml Queue Redis requests RGB Sanctum save selenium SEO Shadowsock Shadowsocks ShadowsocksR simplemde Spring Boot SQLServer ssd SSH ssl SSL证书 SSR str Sublime sudo swap Swift Tensorflow TensorflowLite Terminal Terminator timestamp Ubuntu urllib UTC v2ray Valet Validation Validator VienBlog virtualenvs VPN VPS Vultr Web Windows WordPress Xcode xlsx yaml YAPI YUV zip zmq zsh 上网 下载图片 主从同步 云主机 云存储 云开发 云服务器 人工智能 代码管理 优化 优惠码 伪原创 作弊与反作弊 免费ss账号 免费提现 切片 前端 加密 协议 博客 友链 双击事件 后台运行 后端 命令 国内镜像源 图标 图片操作 图片转换 域名 多身份认证 大小写转换 姿态检测 安卓模拟器 安装 定时任务 定时执行 密码 密钥 导出导入 小程序码 延迟加载 异常 微信 微信小程序 快捷方式 慢查询 懒加载 提现 搜索引擎 搬瓦工 搭梯子 教程 数据库 数据重复 文件上传 无法登录 日志 日期 时区 时间 时间戳 服务器 机器学习 权限 梯子 模拟浏览器 港版支付宝 漏洞 爬虫 生活服务 用户管理 病毒 登录 目标检测 科学上网 系统升级 索引 组件 组件开发 编辑器 自动付款 自定义组件 英文伪原创 计划任务 计算机视觉 订阅通知 认证 语法 读写分离 远程仓库 远程连接 配置文件 重定向 错误异常 错误提示 队列 阿里云 香港 香港手机号
亲情非友情链接