如何合并两个具有Heroku上相同模式的数据库?

我创建了两个在heroku上基本相同的应用程序。 他们开始时不同,因为我正在测试上传到heroku并且在进行调整时遇到了一些挑战。

但现在事情似乎有效,但两者都有我希望巩固的数据。 由于它们运行相同的git存储库,因此代码与迁移相同。

似乎我需要在本地将其归结并合并,但不清楚如何做到这一点。 在Google上进行了一些搜索并没有明确的说明

我想逐步提供一些帮助,我没有明确的流程。

1)我在heroku上有两个应用程序,我有数据库。 他们有相同的模式;

2)我不需要知道数据的来源:我只需要将它们全部放在一个数据库中

3)我希望能够使用特定的sql命令,而不是手动打开(不确定我将如何做),然后重复,因为有大约10个不同的相互关联的表。

谢谢!

没有自动的方法来执行此操作,因为无法以通用方式自动执行此操作(无需执行某些您想要执行的操作)。 因此,它需要几个步骤,但您可以在整个过程中利用工具。

您可以使用Heroku的内置工具来获取表的转储。 首先下载数据并将其导入数据库,然后将其转储到文本文件(SQL格式)中。

在SQL中将其中一个数据集作为文本后,您需要稍微编辑该文件。 您需要使其成为导入脚本,而不是通过删除现有行(或表)开始的“重建数据库”脚本。 如果你小心,它可能已经是正确的格式,但可能会有一些关闭。

你可以遇到一些陷阱:

  • 如果您已经为记录生成了密钥 – 您可能会这样做 – 那么您将必须在要导入的数据集中对它们重新编号。 可能有一种方法可以在没有生成密钥的情况下导出它们,但我所做的是使用快速grep在我合并的数据库范围之外重新编号它们。
  • 如果在其他表中引用了这些键(作为外键),则还必须在那里重新编号。
  • 有些表可能是“引用表”,在两个系统上都是相同的,因此您可以跳过它们。
  • 某些表可能不需要合并。

一旦你有了良好的文本文件,在本地运行并测试它。 如果它搞砸了,请不要担心 – 只需下载生产数据(您要导入的数据),然后再试一次。 迭代,直到你在当地运作良好。 然后,将文件上传到heroku。

我知道这听起来像几步 – 而且确实如此。 但是,没有棘手的问题需要解决。 你只需要慢慢地小心行事。 让某人与你配对,以帮助你思考。

假设您不需要消除重复项,则可以为每个表执行此操作

insert into db1.tablea select * from db2.tablea ; 

一些并发症:

  • 如果表具有id列,则需要通过用新id替换旧ID来确保它们不会发生冲突
  • 但是,由于id是链接表的键,因此需要确保每个表中的新ID匹配。

这是一个快速而肮脏的方法:

  • 在第一个数据库的任何表中查找最高ID。
  • 将此调用称为max_key_db1。
  • 然后将第二个数据库中的所有键更新为current_value加上max_key_db1。

请注意,您需要更新主键和外键才能使其正常工作,例如:

 update db2.tablea set id = id + max_key_db1, foreign_id = foreign_id + max_key_db1; update db2.tableb set id = id + max_key_db1, a_id = a_id + max_key_db1; etc. 

现在,您拥有一个自洽的db2,其中包含所有在db1中不存在的值的主键(主键和外键); 换句话说,您的密钥两个数据库中都是唯一的。

现在您可以将db2中的行插入db1:

 insert into db1.tablea select * from db2.tablea ; 

请注意,如果插入的表使用自动增量或触发器创建自己的ID, 则无效 ; 在这种情况下,您必须明确指定ciolumns并关闭任何自动生成的ID:

 insert into db1.tablea( id, foreign_id, col1, ...) select id, foreign_id, col1 from db2.tablea ; 

或者,您可以通过为每个表一步完成所有操作来保持db2不变:

 insert into db1.tablea( id, foreign_id, col3, col4) select id + max_key_db1, foreign_id + max_key_db1, col3, col4 from db2.tablea ; 

当然,在事务中执行此操作,并且在确定您已获得每个表并且所有表都正确之前不要提交。 并在数据库的副本上执行此操作。

现在,既然您使用了db1中的最高密钥而不管表格,那么您的ID可能不会连续,但是谁在乎呢? 钥匙是钥匙。 您需要做的是为每个表重置任何auto_increment或序列,以便下一个自动生成的密钥高于该表中的最高密钥。 你如何做到这一点取决于你正在使用的RDBMS。

要关闭它 – 决定只手动选择正确的数据并重新输入它,这样我就可以做一些错误检查 – 这很痛苦,但这种方法似乎没有一个简单的答案。 自我注意:将所有生产数据保留在生产中,而不是试驾。

如果您只需要执行一次,则可以使用ms访问轻松完成此操作。

您可以通过在可视化查询设计器中创建一些查询来解决任何冲突。

您可以使用sqllite3的odbc驱动程序连接到sqlite3数据库,并在访问中链接这些表。