Доступ 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

Это должно показать, какие переменные он на самом деле использует для соединения и сделать очевидным, что не так.

Другие вопросы по тегам