在 PostgreSQL 中使用多个模式时找不到 table

Failure to find table when using multiple schemas in PostgreSQL

WPF PostgreSQL 11.1

Npgsql.PostgresException: '42P01: 关系 "testme" 不存在'

当尝试使用具有多个模式的 PostgreSQL 数据库时,我在 App.config 中定义了以下连接字符串。请注意,唯一的区别在于 SearchPath:

 <system.data>
    <DbProviderFactories>
      <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server" type="Npgsql.NpgsqlFactory, Npgsql, Version=4.0.4.0, Culture=neutral" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <clear />
    <add name="localconnection" providerName="Npgsql" connectionString="Server=127.0.0.1;Port=5432;Database=chaos;User Id=postgres;Password=****;Searchpath=nova" />
    <add name="phoenixconnection" providerName="Npgsql" connectionString="Server=127.0.0.1;Port=5432;Database=chaos;User Id=postgres;Password=****;SearchPath=phoenix;" />
  </connectionStrings>

The Npgsql data provider was installed using NuGet: Runtime Version: v4.0.30319 Version: 4.0.4.0

在 PostgreSQL 中,在 Phoenix 模式中:

CREATE TABLE phoenix.testme
(
    name text COLLATE pg_catalog."default" NOT NULL
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE phoenix.testme
    OWNER to postgres;

使用 PgAdmin,显示 testme table 没有问题:

select * from phoenix.testme;

我已经使用上述连接字符串配置了 WCF 服务。使用 PetaPoco,我编写了以下脚本:

public string SayHello()
    {
        string msg;
        using (var db = new chaosDB("phoenixconnection"))
        {
            var m = db.ExecuteScalar<string>("select version()");
            msg = string.Format("Hello from {0}", m);

            m = db.ExecuteScalar<string>("select current_schema");
            msg = string.Format("{0} Current Schema is {1}", msg, m);

            var ss = db.ExecuteScalar<string>("show search_path");


            var s = db.Fetch<string>("select * from testme"); <---THIS FAILS!
            msg = string.Format("{0} I Am {1}", msg, m);

        }
        return msg;
    }

在执行 "select * from testme" 之前一切正常,当我收到上述错误时。注意:来自 "show search_path" returns 的 ss 与 "phoenix"

正确

我做错了什么?我如何让它工作?

非常感谢任何帮助?

绞尽脑汁后答案不言而喻。首先,我重置了数据库中的 search_path。这没有帮助。然后我用 PetaPoco 重建了 POCO,很快发现不仅没有创建新的 table、"testme",而且也没有创建任何 POCO。因此,检查后,PetaPoco 中的 Database.tt 文件显示它具有错误的 ConnectionStringName。将 ConnectionStringName 更改为 "phoenixconnection" 允许构建 POCO,但再次找不到 "testme" table.

然后错误就很明显了,如上所述,"phoenixconnection"和"localconnection"都指向同一个端口。从以前的开发中,我在与较新的 PostgreSQL v11.1 相同的端口上安装了 PostgreSQL v10.1 运行ning。显然,第一个 PostgreSQL v10.1 正在接收连接(而不是更新的 PostgreSQL v11.1)。

转到服务 (services.msc) 并关闭 v10.1 和 运行ning Database.TT 现在出现错误: System.InvalidOperationException:序列包含多个匹配元素

显然 v10.1(我用于开发)只有一个模式,但 v11.1 有多个模式。我认为错误消息意味着 PetaPoco 看到多个 table 具有相同的 table 名称——即,它没有区分模式。

那么,问题就解决了。

  1. 修复端口!较旧的单模式 PostgreSQL v10.1 保留在端口:5432 上。 较新的多模式 PostgreSQL 保留在端口 5433 上。v10.1 将用于 POCO。
  2. 修复 WCF App.config 中的连接字符串,以便在 运行 时,WCF 将使用较新的 v11.1。生成后,保留 POCO,并在 WCF 文件中引用它们。

显然,PetaPoco 在生成其 POCO 时只能使用一个模式,但在 运行 时将从 WCF 的 App.Config 读取连接字符串以执行其查询等。 (因此,在 Database.TT 所在的 App.config 中,将 PetaPoco 指向只有一个模式的 "development" 数据库,但在 WCF 环境中,将连接字符串指向具有多个模式的新数据库. 连接字符串的 SearchPath IS 在 运行ning 通过 Npgsql 时被尊重).

如果 PetaPoco 可以在多模式环境中生成特定于模式的 POCO 就好了,但目前,我想它不能:(

附录注意:事实证明,给定的 PostgreSQL 实例可以有 多个 DATABASES。因此,如果 Npgsql 的连接字符串特定于开发数据库——即只有一个模式的数据库——那么在开发过程中,PetaPoco 可以很好地创建 POCO。然后可以将这些 POCO 直接用于 WCF 服务项目并上传到 IIS 网站。然后可以将网站的 App.config 文件定向为使用 运行-time 数据库(再次在连接字符串中)到已部署的数据库。一切正常! :)