› 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 · Oct 17, 2016 · 3830 views
    This topic created in 3655 days ago, the information mentioned may be changed or developed.

    说明

    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 replies  •  2016-10-18 21:00:14 +08:00
    bwangel
        1
    bwangel  
    OP
       Oct 18, 2016
    @sujin190 放了一天,没人理我,只好又来后者脸皮找你了。

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

    请问一下那个链接重复读,链接指的是和 MySQL 的链接吗?
    sujin190
        5
    sujin190  
       Oct 18, 2016
    @bwangel 是的, mysql 不支持连续发送两条 command 的吧
    bwangel
        6
    bwangel  
    OP
       Oct 18, 2016
    @sujin190 ,这个 command ,应该不是是 SQL 语句吧?

    咋感觉不懂的越来越多了。。。
    sujin190
        7
    sujin190  
       Oct 18, 2016
    @bwangel 。。就是指 sql
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3143 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 13:49 · PVG 21:49 · LAX 06:49 · JFK 09:49
    ♥ Do have faith in what you're doing.