python-trio / trio-mysql Goto Github PK
View Code? Open in Web Editor NEWThis project forked from pymysql/pymysql
Pure Python MySQL Client
Home Page: https://pymysql.readthedocs.io/en/latest/
License: MIT License
This project forked from pymysql/pymysql
Pure Python MySQL Client
Home Page: https://pymysql.readthedocs.io/en/latest/
License: MIT License
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
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.
read_timeout
need to be implemented within the Connection object as it's too helpful .
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'
Despite the documentation, the parameter does not default to true.
It looks OK on master, but 1.0.3 is still the newest stable version on PyPI, hence this bug report.
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
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?
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 |
+----+--------------------------------------+
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)
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
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"}]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.