PostgreSQL添加约束而不破坏数据

时间:2019-01-12 18:14:31

标签: c# postgresql foreign-keys

我正在编写我的应用程序的新版本,该版本添加了功能并修复了一些现有问题。为了无缝升级,我有一个DBVersion值,每个新版本都会增加该值。当我的程序第一次打开时,它将进行任何升级以使数据库保持最新状态。

简化代码:

if (dbVersion < 7)
{
    //make schema changes as needed
}

现在,我遇到一个customers表,其中包含从QuickBooks中检索到的客户。目前,我也有一个包含“客户”字段的订单表。问题在于,由于客户名称用于主键,并且订单表中没有外键关系,因此如果更改客户名称,最终会导致数据损坏。为了解决这种情况,我计划将一个QBID字段添加到客户表。这是一个永久性ID,即使客户名称发生更改,该ID也保持不变。为了添加QBID字段,我需要删除所有客户,添加列(NOT NULL),然后使用QBID字段重新添加客户。

DELETE FROM Customers;
ALTER TABLE customers ADD COLUMN IF NOT EXISTS qbid Character Varying( 20 );
ALTER TABLE customers DROP CONSTRAINT IF EXISTS unique_customers_QBID;
ALTER TABLE customers ADD CONSTRAINT unique_customers_QBID UNIQUE(qbid);

问题在于,直到导入新的客户数据(在数据库架构更新之后),否则我的所有客户字段都将设置为null,我才能添加外键约束。

update orders set customer = null where id in 
    (Select o.id from orders o left join customers c on c.name = o.customer where c.name is null);
ALTER TABLE orders ADD CONSTRAINT lnk_customers_orders FOREIGN KEY (customer) 
    REFERENCES customers ("name") MATCH FULL ON DELETE No Action ON UPDATE Cascade;

为了使事情变得更加困难,获取商品的程序是一个单独的应用程序,在更新架构时,我无法要求获取更新的客户信息。

我已经考虑过跳过DBversion编号,并在第一次导入客户数据后使用它来更新架构。这种方法的问题在于,从QB更新客户时,我将永远需要检查数据库版本。

UpdateCustomers();
var DBVersion = GetDBVersion();
if (DBVersion < 8) UpdateSchema(8);

是否有更好的方法使升级过程变得无缝?

0 个答案:

没有答案