Доступ PyMySQL запрещен "с использованием пароля (нет"), но с использованием пароля
Headscratcher здесь для меня.
Я пытаюсь подключиться к базе данных на моей локальной установке MySQL 8.0.11.0 из Python.
Вот код, который я использую:
conn = pymysql.connect(host='localhost', port=3306, user='root', password='placeholder', db='CustomerInfo')
Python возвращает следующее:
Traceback (most recent call last):
File "D:\Python\FileCheck.py", line 38, in <module>
conn = pymysql.connect(host='localhost', port=3306, user='root', password='placeholder', db='CustomerInfo')
File "C:\Program Files\Python36\lib\site-packages\pymysql\__init__.py", line 90, in Connect
return Connection(*args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 704, in __init__
self.connect()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 974, in connect
self._request_authentication()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 1203, in _request_authentication
auth_packet = self._read_packet()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 1059, in _read_packet
packet.check_error()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 384, in check_error
err.raise_mysql_exception(self._data)
File "C:\Program Files\Python36\lib\site-packages\pymysql\err.py", line 109, in raise_mysql_exception
raise errorclass(errno, errval)
pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: NO)")
Я подтвердил, что у меня есть доступ к базе данных при входе через MySQL Workbench. Странно то, что Python говорит мне "using password: NO"
хотя я отправляю пароль.
Я пытался изменить passwd
в "password"
в сценарии и создание нового пользователя с соответствующими привилегиями. Ни один не работал.
Не уверен, что проверить дальше.
РЕДАКТИРОВАТЬ: Вот гранты для root:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `root`@`localhost` WITH GRANT OPTION
GRANT BACKUP_ADMIN,BINLOG_ADMIN,CONNECTION_ADMIN,ENCRYPTION_KEY_ADMIN,GROUP_REPLICATION_ADMIN,PERSIST_RO_VARIABLES_ADMIN,REPLICATION_SLAVE_ADMIN,RESOURCE_GROUP_ADMIN,RESOURCE_GROUP_USER,ROLE_ADMIN,SET_USER_ID,SYSTEM_VARIABLES_ADMIN,XA_RECOVER_ADMIN ON *....
GRANT ALL PRIVILEGES ON `customerinfo`.* TO `root`@`localhost` WITH GRANT OPTION
GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION
РЕДАКТИРОВАТЬ 2: Добавлены линии отладки для подключения и _request_authentication в connections.py.
Вот последний:
C:\Users\Paul Miller>python.exe D:\Python\FileCheck.py
** DEBUG 1 **
connect, line 973
host= localhost
user= root
password= placeholder
** DEBUG 2 **
_request_authentication line 1172
user= root
password= placeholder
Traceback (most recent call last):
File "D:\Python\FileCheck.py", line 38, in <module>
conn = pymysql.connect(host='localhost', port=3306, user='root', password='placeholder', db='CustomerInfo')
File "C:\Program Files\Python36\lib\site-packages\pymysql\__init__.py", line 90, in Connect
return Connection(*args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 704, in __init__
self.connect()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 982, in connect
self._request_authentication()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 1218, in _request_authentication
auth_packet = self._read_packet()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 1067, in _read_packet
packet.check_error()
File "C:\Program Files\Python36\lib\site-packages\pymysql\connections.py", line 384, in check_error
err.raise_mysql_exception(self._data)
File "C:\Program Files\Python36\lib\site-packages\pymysql\err.py", line 109, in raise_mysql_exception
raise errorclass(errno, errval)
pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: NO)")
РЕДАКТИРОВАТЬ 3: Включено ведение журнала. Никаких неожиданностей в журнале, но вот что сгенерировала последняя попытка:
2018-05-15T10:27:15.197445Z 43 Connect root@localhost on CustomerInfo using TCP/IP
2018-05-15T10:27:15.197540Z 43 Connect Access denied for user 'root'@'localhost' (using password: NO)
РЕДАКТИРОВАТЬ 4: нашел проблему. Я добавил несколько отладочных операторов следующим образом:
if self._auth_plugin_name in ('', 'mysql_native_password'):
print("** DEBUG 3 **")
print(self.password)
print("\n")
authresp = _scramble(self.password.encode('latin1'), self.salt)
Проблема в том, что этот блок IF не работает... поток программы не доходит до оператора "authresp". Когда мой коллега запускает эту же программу, его пароли печатаются в консоли.
Итак, теперь мне просто нужно выяснить, почему я не иду вниз по этой ветке.
3 ответа
Решена проблема после понижения MySQL с 8.0.11.0 до 5.7.22.
В дополнение к тому, что я перечислил в своем первоначальном вопросе, я также попробовал следующее:
- Установленная нижняя версия PyMySQL (от 0.8.1 до 0.8.0 в моем случае)
- Полностью удалены обе версии PyMySQL и установлен v0.8.0
- Удален MySQL 8.0 и переустановлен
Когда ничего из вышеперечисленного не сработало, я понизил MySQL до v5.7, что и использует один из моих коллег. Это решило ошибку.
Одна из возможных причин этой проблемы -
PyMySQL
версия
0.8.x
или ниже. Если это так, проблему можно решить, обновив его в pip до
PyMySQL==0.9.3
.
Это странно. Я бы установил pymysql в виртуальной среде, а затем удалил несколько строк отладки в этой функции:
https://github.com/PyMySQL/PyMySQL/blob/master/pymysql/connections.py
Это должно показать, какие переменные он на самом деле использует для соединения и сделать очевидным, что не так.