V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
bwangel
V2EX  ›  MySQL

TorMySQL 封装的 async with 语句抛出了 AssertionError 异常

  •  
  •   bwangel ·
    bwangelme · 2016-10-17 17:27:42 +08:00 · 3092 次点击
    这是一个创建于 2765 天前的主题,其中的信息可能已经有所发展或是发生改变。

    说明

    1. 我的数据库和表都是没有问题的,不会有数据库不存在或者表结构错误的情况
    2. 我用的是tornado 4.4.2,Tornado的文档中说到 Tornado 4.3后就支持Python 3中的async/await 关键字了。

    正文

    我这两天了解了一下 Python3 中的 async/await 语句,然后照猫画虎,对 TorMySQL 封装了一个 async with语句的上下文管理器:

    代码如下:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    
    from tornado.ioloop import IOLoop
    import tormysql
    
    class get_cursor:
        def __init__(self, pool):
        	""" get_cursor 上下文管理器
            
            针对`async with`语句封装的上下文管理器
            """
            self.pool = pool
    
        async def __aenter__(self):
            self.tx = await self.pool.begin()
            return self.tx
    
        async def __aexit__(self, exc_type, exc, tb):
            if tb is None:
                self.tx.commit()
            else:
                self.tx.rollback()
    
    async def insert():
        pool = tormysql.helpers.ConnectionPool(
            max_connections = 20, #max open connections
            idle_seconds = 7200, #conntion idle timeout time, 0 is not timeout
            wait_connection_timeout = 3, #wait connection timeout
            host = "127.0.0.1",
            user = "root",
            passwd = "TEST",
            db = "test",
            charset = "utf8"
        )
        async with get_cursor(pool) as cursor:
            cursor.execute("INSERT INTO test(id) VALUES(1)")
    
    ioloop = IOLoop.instance()
    ioloop.run_sync(insert)
    

    我执行了上述代码以后,抛出了如下的错误:

    ➜ /home/yundongx/tutorial/async [async]$ python3 async.py
    ERROR:tornado.application:Future <tornado.concurrent.Future object at 0x7f1983708470> exception was never retrieved: Traceback (most recent call last):
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tornado/gen.py", line 1021, in run
        yielded = self.gen.throw(*exc_info)
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tormysql/helpers.py", line 44, in commit
        yield self._connection.commit()
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tornado/gen.py", line 1015, in run
        value = future.result()
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tornado/concurrent.py", line 237, in result
        raise_exc_info(self._exc_info)
      File "<string>", line 3, in raise_exc_info
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tormysql/util.py", line 14, in finish
        result = fun(*args, **kwargs)
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/pymysql/connections.py", line 767, in commit
        self._read_ok_packet()
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/pymysql/connections.py", line 746, in _read_ok_packet
        pkt = self._read_packet()
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/pymysql/connections.py", line 961, in _read_packet
        packet_header = self._read_bytes(4)
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tormysql/connections.py", line 308, in _read_bytes
        future = self._rfile.read_bytes(num_bytes)
      File "/home/yundongx/.virtualenvs/async/lib/python3.5/site-packages/tormysql/connections.py", line 97, in read
        assert self._read_future is None, "Already reading"
    AssertionError: Already reading
    Exception ignored in: <generator object execute at 0x7f19836e2e60>
    RuntimeError: generator ignored GeneratorExit
    WARNING:root:Transaction has not committed or rollbacked <tormysql.connections.Connection object at 0x7f19837080b8> {'user': b'root', 'port': 3306, 'host': '127.0.0.1', 'database': b'test'}.
    

    然后我去数据库中查询这个表,发现数据已经插入成功了。

    请问一下这个异常是什么意思啊( PyMySQL 显示说Already reading是什么意思啊)?

    7 条回复    2016-10-18 21:00:14 +08:00
    bwangel
        1
    bwangel  
    OP
       2016-10-18 10:38:46 +08:00
    @sujin190 放了一天,没人理我,只好又来后者脸皮找你了。

    能大概给个方向吗,这个从哪里下手解决啊。我感觉一头雾水,这个错误。
    sujin190
        2
    sujin190  
       2016-10-18 13:15:31 +08:00   ❤️ 2
    cursor.execute
    self.tx.commit
    self.tx.rollback
    这三个前面都少了 await 关键字了吧
    否则你 execute 刚发出去,不等待数据库返回就直接进入了 commit 了,这样就是对链接重复读了么
    sujin190
        3
    sujin190  
       2016-10-18 13:16:23 +08:00
    @sujin190 Already reading 这个错误大多都是这个问题,少 await 关键字或是少 yield 关键字
    bwangel
        4
    bwangel  
    OP
       2016-10-18 16:56:42 +08:00
    @sujin190 ,确实。

    请问一下那个链接重复读,链接指的是和 MySQL 的链接吗?
    sujin190
        5
    sujin190  
       2016-10-18 19:44:09 +08:00
    @bwangel 是的, mysql 不支持连续发送两条 command 的吧
    bwangel
        6
    bwangel  
    OP
       2016-10-18 20:53:33 +08:00
    @sujin190 ,这个 command ,应该不是是 SQL 语句吧?

    咋感觉不懂的越来越多了。。。
    sujin190
        7
    sujin190  
       2016-10-18 21:00:14 +08:00
    @bwangel 。。就是指 sql
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3368 人在线   最高记录 6547   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:39 · PVG 20:39 · LAX 05:39 · JFK 08:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.