代码之家  ›  专栏  ›  技术社区  ›  Alan Wayne

在PostgreSQL中使用多个架构时找不到表

  •  1
  • Alan Wayne  · 技术社区  · 5 年前

    WPF PostgreSQL 11.1

    npgsql.postgresException:关系“testme”不存在

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

     <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>
    

    使用nuget:runtime版本安装了npgsql数据提供程序: v4.0.30319版本: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表没有问题:

    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”之前,一切都正常工作。注:“显示搜索路径”中的ss用“phoenix”正确返回

    我做错什么了?我怎样才能让这个工作??

    最感谢你的帮助?

    1 回复  |  直到 5 年前
        1
  •  0
  •   Alan Wayne    5 年前

    经过长时间的挠头之后,答案变得不言而喻。首先,我重置了数据库中的搜索路径。这没有帮助。然后我用petapoco重新构建了poco,很快发现不仅是新的表“testme”,没有创建,也没有任何poco的表。因此,通过检查,petapoco中的database.tt文件显示它有错误的connectionStringName。将connectionStringName更改为“phoenixConnection”允许生成POCO,但再次未能找到“testme”表。

    然后,正如上面所述,错误变得很明显,“phoenixconnection”和“localconnection”都指向同一个端口。在以前的开发中,PostgreSQL v10.1与更新的PostgreSQL v11.1在同一个端口上运行。显然,第一个PostgreSQL v10.1正在接收连接(而不是更新的PostgreSQL v11.1)。

    转到services(services.msc)并关闭v10.1并运行database.tt,现在出现错误: System.InvalidOperationException:序列包含多个匹配元素

    显然v10.1(我用于开发)只有一个模式,但v11.1有多个模式。我认为错误消息的意思是Petapoco看到了多个具有相同表名的表——也就是说,它没有区分模式。

    所以问题现在解决了。

    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指向只有一个模式的“开发”数据库,但在wcf环境中,将co指向将字符串连接到具有多个架构的新数据库。连接字符串的搜索路径 在运行npgsql时受到尊重)。

    如果Petapoco能够在多模式环境中生成特定于模式的Poco,那就太好了,但是目前,我想它不能:(