在 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 名称——即,它没有区分模式。
那么,问题就解决了。
- 修复端口!较旧的单模式 PostgreSQL v10.1 保留在端口:5432 上。
较新的多模式 PostgreSQL 保留在端口 5433 上。v10.1 将用于 POCO。
- 修复 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 数据库(再次在连接字符串中)到已部署的数据库。一切正常! :)
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 名称——即,它没有区分模式。
那么,问题就解决了。
- 修复端口!较旧的单模式 PostgreSQL v10.1 保留在端口:5432 上。 较新的多模式 PostgreSQL 保留在端口 5433 上。v10.1 将用于 POCO。
- 修复 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 数据库(再次在连接字符串中)到已部署的数据库。一切正常! :)