如何验证 mysql 数据库 URI

How to validate mysql database URI

我正在尝试将 Gem 命名的西装外套与我的 Rails 应用程序集成,我必须在 blazer.yml 文件中指定 mysql 数据库 URL以便它可以访问登台和生产环境中的数据。

我相信定义 MySQL 数据库 URL 的标准格式是

mysql2://user:password@hostname:3306/database

我将 URL 定义为与字符串相同的格式,当我验证 URI 时,出现以下错误

URI::InvalidURIError: bad URI(is not URI?): mysql2://f77_oe_85_staging:LcCh%264855c6M;kG9yGhjghjZC?JquGVK@factory97-aurora-staging-cluster.cluster-cmj77682fpy4kjl.us-east-1.rds.amazonaws.com/factory97_oe85_staging

已定义 Mysql 数据库 URL:

'mysql2://f77_oe_85_staging:LcCh%264855c6M;kG9yGhjghjZC?JquGVK@factory97-aurora-staging-cluster.cluster-cmj77682fpy4kjl.us-east-1.rds.amazonaws.com/factory97_oe85_staging'

请指教

URI 无效。

问题是密码包含 URI 中无效的字符。 username:password 是 URI 的 userinfo 部分。从 RFC 3986...

  foo://example.com:8042/over/there?name=ferret#nose
  \_/   \______________/\_________/ \_________/ \__/
   |           |            |            |        |
scheme     authority       path        query   fragment

authority   = [ userinfo "@" ] host [ ":" port ]
userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )

pct-encoded = "%" HEXDIG HEXDIG
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
            / "*" / "+" / "," / ";" / "="

具体就是密码LcCh%264855c6M;kG9yGhjghjZC?JquGVK中的?。看起来密码只是部分转义。

我认为问题是问题没有很好地隔离。这是一个 示例 如何隔离它的策略。

URI::InvalidURIError: bad URI(is not URI?):的错误码只表示库(blazergem)成功读取了一个文件,可能是也可能不是你编辑的文件,/YOUR_DIR/blazer.yml什么的, 但仍无法解析 URI。

现在,要考虑的问题包括:

  1. 西装外套gem真的看过/YOUR_DIR/blazer.yml?
  2. yml 的预处理器是否按预期工作?
  3. 指定的 uri 键是否正确?
  4. mysql:mysql2?
  5. IP、端口、账户名、密码、数据库名的格式都正确吗?特别是,特殊字符是否正确转义? (参见 MySql document about special characters

我想 OP 知道其中一些问题的答案,但我们不知道。因此,让我们假设其中任何一个都可能成为问题。

那么建议的策略是:

  1. 找到一个至少格式正确的 URI,并确认它被 Gem blazer 正确解析和识别。请注意,您只需要测试格式,因此虚拟参数就可以了。例如,尝试以下组合,看看哪个不会发出错误 URI::InvalidURIError:

    1. mysql://127.0.0.1/test
    2. mysql://adam:alphabetonly@127.0.0.1/test
    3. jdbc:mysql://adam:alphabetonly@127.0.0.1/test

    现在,您至少知道潜在问题 (1)、(3)、(4) 是无关紧要的。

  2. 将IP(主机名)、账户名、密码、数据库名一一替换为真实的,找出哪个引发错误URI::InvalidURIError。现在您已经缩小了导致问题的部分的范围。在 OP 的情况下,我怀疑问题是密码部分中特殊字符的不正确转义。假设是这样,那么,
  3. 对部分进行适当的转义,使其整体形成正确的URI格式。 @Schwern 的回答很好地总结了格式。作为提示,您可以通过打开 Rail 的控制台(通过 rails c)并键入 URI.encode('YOUR_PASSWORD') 或直接从命令行中输入 运行 ruby 来获取转义 URI (UNIX-shell) 终端:

    ruby -ruri -e "puts URI.encode('YOUR_PASSWORD')"
    

    /YOUR_DIR/blazer.yml中URI中的密码部分替换为转义后的字符串,并确认不会报错URI::InvalidURIError(希望如此)。

在这些处理中,我特意避开了预处理器部分,(2)。 到 "Rails not parsing database URL on production" 在 yml 文件中提到了 URI.encode('YOUR_PASSWORD'),但它隐含地假设预处理器工作正常。在测试阶段,这只会增加另一层复杂性,因此最好跳过它。如果您在生产中需要它(屏蔽密码等),请稍后在您知道其他一切正常时实施它。

希望在 OP 尝试所有这些时,问题已解决。