首页 > 解决方案 > 如何将数据从一个 GRAPH 复制到另一个?

问题描述

我正在运行数据库 Agens Graph v.2.1.0。我创建了两个具有相同结构的图,例如 1 个顶点标签“VERTEX”和 1 个边标签“EDGE”。如何将数据从一个图表复制到另一个图表?我无法使用 sql 查询从 ag_edge、ag_vertex 表中复制数据。有没有相关的例子?

也许是创建图形完整副本的函数?

标签: postgresqlgraph-databasesagens-graph

解决方案


我有这里解释的过程和执行它的 go 语言代码。Go 代码可以很容易地用 C 或任何脚本语言重写。这里又是:

在 AgensGraph 数据库中克隆图

AgensGraph是面向现代复杂数据环境的新一代多模型图数据库。

有时,能够将整个图克隆到同一数据库中的另一个图中似乎很有用。AgensGraph 还没有产生这样的实用程序。这是一个用 Go 语言创建这样一个实用程序的尝试。

那么,AgensGraph 中的 Graph 是什么?

AgensGraph 是 PostgreSQL 的扩展。因此,在 AgensGraph 中,图是一个模式(包含数据的表集)和表 pg_catalog.ag_label、pg_catalog.ag_graph 和 pg_catalog.ag_graphmeta 中的一些元数据。数据是一组表,其索引包含有关连接它们的顶点和边的信息。

那么,克隆图是什么意思呢?

显然,这意味着创建一个new_schema,它将作为原始模式的副本(为简洁起见,我们将其称为 old_schema),并在上面提到的表中正确设置元数据。

为什么这很难做到?

  1. AgensGraph 没有执行此操作的实用程序。
  2. AgensGraph 文档中没有描述,
  3. AgensGraph 禁止对属于图形的表进行许多表操作。

如何在 PostgreSQL 中复制模式?

PostgreSQL 中描述:如何在同一数据库中创建数据库模式的完整副本?. 不久:

psql -U user -d dbname -c 'ALTER SCHEMA old_schema RENAME TO new_schema'
pg_dump -U user -n new_schema -f new_schema.sql dbname
psql -U user -d dbname -c 'ALTER SCHEMA new_schema RENAME TO old_schema'
psql -U user -d dbname -c 'CREATE SCHEMA new_schema'
psql -U user -q -d dbname -f new_schema.sql
rm new_schema.sql

为了成功,我们需要在重命名 old_schema 之前从 ag_graph 表中删除 old_schema,然后在创建新模式之前将其添加回来 - 否则 AgnsGraph 触发器将禁止模式重命名(参见 Go 代码)。

如何处理 ag_graph 表?

agens=# \d ag_graph;
            Table "pg_catalog.ag_graph"
  Column   | Type | Collation | Nullable | Default
-----------+------+-----------+----------+---------
 graphname | name |           | not null |
 nspid     | oid  |           | not null |
Indexes:
    "ag_graph_graphname_index" UNIQUE, btree (graphname)
    "ag_graph_oid_index" UNIQUE, btree (oid)

graphname == new_schema , nspid 取自

agens=# SELECT oid FROM pg_namespace WHERE nspname='new_schema';
  oid
-------
 16418
(1 row)

如何处理 ag_label 表?

16419 == (nspid+1) of old_schema

agens=# SELECT * FROM ag_label WHERE graphid=16419;
  labname  | graphid | labid | relid | labkind
-----------+---------+-------+-------+---------
 ag_vertex |   16419 |     1 | 16424 | v
 ag_edge   |   16419 |     2 | 16438 | e
 person    |   16419 |     3 | 16453 | v
 knows     |   16419 |     4 | 16467 | e
(4 rows)

我们需要从 pg_class 复制所有具有相同 labname、labid、labkind 和 new graphid == (nspid+1) 的new_schema和 relid == relfilenode 的记录:

agens=# SELECT relname, relfilenode FROM pg_class WHERE relnamespace=16418;
      relname      | relfilenode
-------------------+-------------
 ag_label_seq      |       16420
 knows             |       16467
 ag_vertex_pkey    |       16433
 ag_vertex_id_seq  |       16435
 ag_edge_id_idx    |       16447
 ag_edge_start_idx |       16448
 ag_edge_end_idx   |       16449
 ag_edge_id_seq    |       16450
 ag_vertex         |       16424
 person            |       16453
 person_pkey       |       16462
 person_id_seq     |       16464
 ag_edge           |       16438
 knows_id_idx      |       16476
 knows_start_idx   |       16477
 knows_end_idx     |       16478
 knows_id_seq      |       16479
(17 rows)

relnamespacenew_schema的一个 nspid ,所有的索引和主键都需要被忽略,只需要复制表。

如何处理 ag_graphmeta 表?

我不知道 - 在我的情况下它总是空的。

以上所有对我来说都是一个计划 - 所以,我尝试用一​​个简单的 Go 语言实用程序来实现它https ://github.com/tbolsh/CloneAgensGraph


推荐阅读