【问题标题】:OSX El Capitan sqlalchemy Can't connect to MySQL server on '127.0.0.1' (111)OSX El Capitan sqlalchemy 无法连接到“127.0.0.1”上的 MySQL 服务器 (111)
【发布时间】:2018-01-31 02:48:04
【问题描述】:

此应用程序中的 python 从 docker 容器运行。容器在网络模式下运行:“host”。

我无法通过 python 包 sqlalchemy 连接到 MySQL 数据库。我收到以下错误。

OperationalError: (OperationalError) (2003, "Can't connect to MySQL 服务器在 '127.0.0.1' (111)") 无 无

以下终端命令可以正常工作

mysql -h 127.0.0.1 -u my_user --password='password' db -e "SHOW TABLES;"
enter code here

也许 sqlalchemy 没有使用您所说的正确配置?在第一次连接 MySQL 之前,我已经在调试行中打印了配置:

  print config.get('repository', 'host') // 127.0.0.1
  print config.get('repository', 'user') // my_user
  print config.get('repository', 'passwd') // password

也许该配置仍然没有进入 sqlalchemy?让我们打印出引擎字符串

  engine = getUnaffiliatedEngine()
  print engine //Engine(mysql://my_user:***@127.0.0.1:3306)
  with engine.connect() as connection:
    for s in statements:
      if s.strip():
        connection.execute(s)

也许有超过 1 个版本的 mysql 正在运行?只有一个进程在运行:

ps -ef | grep mysql

74 15459 1 0 10:14 ?? 0:00.80 /usr/local/mysql/bin/mysqld --user=_mysql

也许该用户无权访问数据库?

mysql> select User, Host from mysql.user;

+------+--------------------------+
| User | Host                     |
+------+--------------------------+
|my_user 127.0.0.1                |
| root | 127.0.0.1                |
| root | ::1                      |
|      | localhost                |
| root | localhost                |
+------+--------------------------+

类似地“显示数据库”显示数据库存在。我已为每个数据库授予该用户的所有权限。我也刷了privs。

也许某种防火墙规则正在停止连接?我使用了小告密者,并且整个防火墙已被拆除以进行测试。

此时我什至不知道还要调试什么。以下是引发连接错误的 Python 脚本的简化版本:

DSN_FORMAT = "mysql://%(user)s:%(passwd)s@%(host)s:%(port)s"

def getDSN():
  return DSN_FORMAT % dict(config.items("repository"))

def getUnaffiliatedEngine():
  return create_engine(getDSN())

def reset(offline=False):
  config.loadConfig()
  dbName = config.get('repository', 'db')
  print config.get('repository', 'host')
  print config.get('repository', 'user')
  print config.get('repository', 'passwd')

  resetDatabaseSQL = (
      "DROP DATABASE IF EXISTS %(database)s; "
      "CREATE DATABASE %(database)s;" % {"database": dbName})
  statements = resetDatabaseSQL.split(";")

  engine = getUnaffiliatedEngine()
  print engine
  with engine.connect() as connection:
    for s in statements:
      if s.strip():
        connection.execute(s)

这是tcpdump -i lo0 port 3306 的输出:

11:44:41.224036 IP localhost.58797 > localhost.mysql: Flags [P.], seq 3915736486:3915736498, ack 2134634265, win 12519, options [nop,nop,TS val 980567261 ecr 980503692], length 12
11:44:41.224105 IP localhost.mysql > localhost.58797: Flags [.], ack 12, win 12737, options [nop,nop,TS val 980567261 ecr 980567261], length 0
11:44:41.224178 IP localhost.mysql > localhost.58797: Flags [P.], seq 1:19, ack 12, win 12737, options [nop,nop,TS val 980567261 ecr 980567261], length 18
11:44:41.224218 IP localhost.58797 > localhost.mysql: Flags [.], ack 19, win 12519, options [nop,nop,TS val 980567261 ecr 980567261], length 0
11:45:07.422776 IP localhost.58796 > localhost.mysql: Flags [P.], seq 2953728354:2953728366, ack 432872138, win 12483, options [nop,nop,TS val 980593366 ecr 980533534], length 12
11:45:07.422807 IP localhost.mysql > localhost.58796: Flags [.], ack 12, win 12729, options [nop,nop,TS val 980593366 ecr 980593366], length 0
11:45:07.422856 IP localhost.mysql > localhost.58796: Flags [P.], seq 1:19, ack 12, win 12729, options [nop,nop,TS val 980593366 ecr 980593366], length 18
11:45:07.422877 IP localhost.58796 > localhost.mysql: Flags [.], ack 19, win 12482, options [nop,nop,TS val 980593366 ecr 980593366], length 0

MySQL 5.6 OSX El Capitan 10.11.6

【问题讨论】:

  • 你能显示给出错误的实际代码吗?或者至少是它的简化版本。
  • 我同意@gsi-frank - 一个简单的 SQLAlchemy 引擎和connection setup (like in its docs) 的简化示例在这里会有所帮助(既可以简化调试,也可以解决关于 SO 的问题)。
  • @gsi-frank 完成
  • 111Connection refused。因此,您的 MySQL 服务器可能只在本地接口上侦听,并且由于某种原因,您的连接尝试似乎通过外部接口路由。谷歌搜索“小飞贼 localhost 连接”会发现人们遇到的几个问题,即使它被禁用。
  • @MarkJones 你能在执行脚本之前做tcpdump -i lo0 port 3306 吗?确保其他人在测试时尝试连接到您的本地 MySQL。这个想法是查看您从哪个地址连接到 MySQL 服务器。

标签: python mysql sqlalchemy osx-elcapitan


【解决方案1】:

您写的最后一条评论非常重要,可能是问题的原因。

我很确定您的 Docker 容器有自己的环回接口,地址为 127.0.0.1,与运行 MySQL 的 OSX 环回接口不同。

我建议您将您的 MySQL 监听设置在从容器内部可见的地址上。您可以从容器内部轻松地调试该配置以生成 telnet ip_address 3306

【讨论】:

  • 如果有人偶然发现这一点,在 OSX 上对 Docker 使用 --network='host' 不能按预期工作,并且 Docker 不会修复它。 OSX 上的 Docker 使用虚拟机,这里的 --network='host' 参数完全被破坏了。通过 Docker 论坛上的 cmets 阅读,这个问题被忽略了,并且不会有任何努力解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 2012-02-08
  • 2016-01-11
  • 2016-12-19
  • 1970-01-01
  • 2016-12-14
相关资源
最近更新 更多