如何在DBI-> connect的参数中使用空格?

Raz*_*erM 8 perl dbi

我正在尝试使用DBI和连接SSL客户端密钥DBD::Pg.

use strict;
use warnings 'all';
use DBI;

my $dsn = "dbi:Pg:db=mydb;sslmode=require;host=localhost;"
    ."sslcert=C:\\path with\\spaces.crt;"
    ."sslkey=C:\\path with\\spaces.key";

my $dbh = DBI->connect( $dsn, 'username', '' );
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Can't connect to database: missing "=" after "with\spaces.crt" in connection info string!
Run Code Online (Sandbox Code Playgroud)

我试过在值周围使用单引号或双引号无效,我在文档中找不到任何内容.

更新

单引号如下:

my $dsn = "dbi:Pg:db=mydb;sslmode=require;host=localhost;"
    ."sslcert='C:\\path with\\spaces.crt';"
    ."sslkey='C:\\path with\\spaces.key'";
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

failed: FATAL:  connection requires a valid client certificate
Run Code Online (Sandbox Code Playgroud)

我知道这个配置有效,因为它适用于Python.

事实证明这是有效的:

my $dsn = "dbi:Pg:db=mydb;sslmode=require;host=localhost;"
    ."sslcert='C:\\\\path with\\\\spaces.crt';"
    ."sslkey='C:\\\\path with\\\\spaces.key'";
Run Code Online (Sandbox Code Playgroud)

为什么我需要双逃逸反斜杠?

Thi*_*Not 4

要在 DSN 中包含包含空格的属性,请用单引号将该值引起来:

my $dsn = q{dbi:Pg:db=mydb;sslmode=require;host=localhost;}
        . q{sslcert='C:\\\path with\\\spaces.crt';}
        . q{sslkey='C:\\\path with\\\spaces.key'};
Run Code Online (Sandbox Code Playgroud)

请注意,用于分隔连接属性的分号必须位于单引号之外。另请注意,属性内的反斜杠和单引号必须使用反斜杠进行转义(您必须使用上面的三个反斜杠,因为 Perl 会转换\\\单引号字符串)。

如果您的 DSN 括在双引号中,则必须使用四个反斜杠,因为 Perl 会像\n双引号字符串中那样插入转义序列:

my $dsn = qq{dbi:Pg:db=mydb;sslmode=require;host=localhost;}
        . qq{sslcert='C:\\\\path with\\\\spaces.crt';}
        . qq{sslkey='C:\\\\path with\\\\spaces.key'};
Run Code Online (Sandbox Code Playgroud)

至于文档,我没有看到 DBD::Pg 中提到这一点,但您可以通过查看源代码看到它是支持的。处理 DSN 的代码位于DBD::Pg 发行版的dbdimp.c中:

my $dsn = q{dbi:Pg:db=mydb;sslmode=require;host=localhost;}
        . q{sslcert='C:\\\path with\\\spaces.crt';}
        . q{sslkey='C:\\\path with\\\spaces.key'};
Run Code Online (Sandbox Code Playgroud)

这会将 DBI 样式的连接字符串转换为libpq 样式的连接字符串(libpq 是 Postgres C API,DBD::Pg 在幕后使用它)。由于生成的 DSN 直接传递给 libpq,因此它需要遵循libpq 文档中描述的引用和转义规则。

DBD::Pg 的文档补丁肯定是合适的。