GithubHelp home page GithubHelp logo

python-trio / trio-mysql Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pymysql/pymysql

11.0 11.0 6.0 1.41 MB

Pure Python MySQL Client

Home Page: https://pymysql.readthedocs.io/en/latest/

License: MIT License

Python 99.54% Makefile 0.46%

trio-mysql's People

Contributors

bbigras avatar boglin avatar brettl-sprint avatar clarkevans avatar clelland avatar cleure avatar djmitche avatar elemount avatar grooverdan avatar hannosch avatar jamadden avatar jcotton1123 avatar jvankoten avatar klondi avatar lecram avatar martinthoma avatar methane avatar mlongtin0 avatar petehunt avatar raggiskula avatar rfk avatar rjollos avatar smurfix avatar tonal avatar vtermanis avatar wiggzz avatar worldexception avatar wraziens avatar yoriksar avatar zzzeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

trio-mysql's Issues

Refactor to (a) get rid of cursors, (b) have a nicer interface

The problem is that mysql doesn't have cursors, so why would you want to fake them?

In an async world you don't need to expose cursors to the user anyway. You want to simply call

    async with trio_mysql.connect("localhost") as db:
        async with db.query("select a,b,c …") as result
            async for a,b,c in result:
                await process_record(a,b,c)

instead. SO, none of that fetch_one, fetch_many or fetch_dict stuff – let the record be a named tuple instead, and/or add some options that describe how the result should look like.

If process needs to run a query (like an update), well, you need to save the not-yet-read results in memory – which you should not do when that is not necessary.

Also, cancelling a query requires sending a "kill" command to the server if not all results have been read (if any). The mysql command line client can do that: if you interrupt a query before it returns any result it asks you whether you want to.

Also, mysql now supports nested transactions. This adapter should support them. It should also refuse to accept queries on the connection (or outer transactions) when a(n inner) transaction is active, i.e.

    async with trio_mysql.connect("localhost") as db:
        await db.query("insert into test values(1)")  # works, auto-commits
        async with db.transaction() as tr:
            await tr.query("insert into test values(2)")  # works
            await db.query("insert into test values(3)")  # raises an error

Example in README doesn't run.

Hello, thanks for the project!

I tried to run the example code in the README, but it doesn't run. You need to run the code inside an event loop.

Also con.commit() is never awaited.

Bug

Traceback (most recent call last):
  File "/root/american/script.py", line 95, in <module>
    trio.run(main, parser.parse_args())
  File "/usr/local/lib/python3.9/site-packages/trio/_core/_run.py", line 1932, in run
    raise runner.main_task_outcome.error
  File "/root/american/script.py", line 72, in main
    nurse.start_soon(
  File "/usr/local/lib/python3.9/site-packages/trio/_core/_run.py", line 815, in __aexit__
    raise combined_error_from_nursery
  File "/root/american/script.py", line 31, in worker
    async with trio_mysql.connect(host=ip, user=user, password=password, connect_timeout=2) as connection:
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 616, in __aenter__
    await self.connect()
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 670, in connect
    await self._request_authentication()
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 974, in _request_authentication
    data = _auth.scramble_old_password(self.password, self.salt) + b"\0"
AttributeError: module 'trio_mysql._auth' has no attribute 'scramble_old_password'

Bug

Traceback (most recent call last):
  File "/root/american/script.py", line 103, in <module>
    trio.run(main, parser.parse_args())
  File "/usr/local/lib/python3.9/site-packages/trio/_core/_run.py", line 1932, in run
    raise runner.main_task_outcome.error
  File "/root/american/script.py", line 80, in main
    nurse.start_soon(
  File "/usr/local/lib/python3.9/site-packages/trio/_core/_run.py", line 815, in __aexit__
    raise combined_error_from_nursery
  File "/root/american/script.py", line 35, in worker
    async with trio_mysql.connect(host=ip, user=user, password=password, connect_timeout=2) as connection:
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 616, in __aenter__
    await self.connect()
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 669, in connect
    await self._get_server_information()
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 1105, in _get_server_information
    packet = await self._read_packet()
  File "/usr/local/lib/python3.9/site-packages/trio_mysql/connections.py", line 742, in _read_packet
    raise err.InternalError(
trio_mysql.err.InternalError: Packet sequence number wrong - got 1 expected 0

Packet sequence number wrong - got 3 expected 1

Describe the bug

This library fails to read database, and sadly after 6 hours of testing I can only say "I don't what's wrong".

One possibility I can think of is trio-mysql not supporting the mysql 8.x, while pymysql does.

Should I just downgrade or switch to sqlalchemy-aio for now?

To Reproduce

Schema:

CREATE DATABASE test_mysql CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
USE test_mysql

CREATE TABLE `test` (
    `id` int NOT NULL AUTO_INCREMENT,
    `val` varchar(1023) COLLATE utf8mb4_0900_ai_ci NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
AUTO_INCREMENT=1;

INSERT INTO test(val) VALUES("test post that shouldn't get deleted");

Should looks like this:

mysql> select * from test;
+----+--------------------------------------+
| id | val                                  |
+----+--------------------------------------+
|  1 | test post that shouldn't get deleted |
+----+--------------------------------------+

Code:

from getpass import getpass
import trio
import trio_mysql


user = input("DB User> ")
pwd = getpass("DB Pwd > ")
db_name = input("DB Name> ")


def get_db():
    conn = trio_mysql.connect(
        host="localhost",
        user=user,
        password=pwd,
        db=db_name,
        charset="utf8mb4",
        cursorclass=trio_mysql.cursors.DictCursor
    )
    print("Created DB connection")
    return conn


async def fetch_db():
    async with get_db() as conn:
        async with conn.cursor() as cur:
            await cur.execute(f"SELECT * FROM test")
            data = await cur.fetchall()
    print(data)


trio.run(fetch_db)

Output

DB User> root
DB Pwd > 
DB Name> test_mysql
Created DB connection
E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py:670: RuntimeWarning: coroutine 'caching_sha2_password_auth' was never awaited
  await self._request_authentication()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "C:\Users\jupiterbjy\AppData\Roaming\JetBrains\PyCharm2021.3\scratches\scratch.py", line 32, in <module>
    trio.run(fetch_db)
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio\_core\_run.py", line 1932, in run
    raise runner.main_task_outcome.error
  File "C:\Users\jupiterbjy\AppData\Roaming\JetBrains\PyCharm2021.3\scratches\scratch.py", line 25, in fetch_db
    async with get_db() as conn:
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py", line 616, in __aenter__
    await self.connect()
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py", line 683, in connect
    await self.autocommit(self.autocommit_mode)
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py", line 442, in autocommit
    await self._send_autocommit_mode()
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py", line 460, in _send_autocommit_mode
    await self._read_ok_packet()
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py", line 448, in _read_ok_packet
    pkt = await self._read_packet()
  File "E:\github\StreamNotifier-Web\venv\lib\site-packages\trio_mysql\connections.py", line 742, in _read_packet
    raise err.InternalError(
trio_mysql.err.InternalError: Packet sequence number wrong - got 3 expected 1

Expected behavior

Equivalent code:

from getpass import getpass
import pymysql


user = input("DB User> ")
pwd = getpass("DB Pwd > ")
db_name = input("DB Name> ")


def get_db():
    conn = pymysql.connect(
        host="localhost",
        user=user,
        password=pwd,
        db=db_name,
        charset="utf8mb4",
        cursorclass=pymysql.cursors.DictCursor
    )
    print("Created DB connection")
    return conn


def fetch_db():
    with get_db() as conn:
        with conn.cursor() as cur:
            cur.execute(f"SELECT * FROM test")
            data = cur.fetchall()
    print(data)


fetch_db()

output:

DB User> root
DB Pwd > 
DB Name> test_mysql
Created DB connection
[{'id': 1, 'val': "test post that shouldn't get deleted"}]

Environment

  • mysql: Ver 8.0.27 for Win64 on x86_64
  • trio-mysql: 1.0.3
  • python 3.10.1 x64 / python 3.9.2 x64
  • trio 0.19.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.