本文档介绍了您在使用 Spanner 图表时可能会遇到的错误。还提供了错误示例和推荐的修复方法。
如果您在查看此问题排查指南后需要进一步的支持,请参阅获取支持。
架构错误
架构结果基于设置和查询 Spanner Graph 中使用的相应数据集。
元素键必须保证唯一性
错误消息
Neither the primary keys nor any unique index defined on the property graph
element source table `Person` provides the uniqueness guarantee for graph
element `Person` belonging to the graph `FinGraph`. You want to redefine the
element key columns (`name`) based on the source table's primary keys, or
create a unique index on the element's key columns.
错误示例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (name)
);
建议的解决方法
在元素键列上创建唯一索引,并根据源表主键重新定义元素键列。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (id)
);
或者,您也可以在元素键列上创建唯一索引。
CREATE UNIQUE INDEX PersonNameIndex ON Person(name);
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person KEY (name)
);
元素定义的名称必须是唯一的
错误消息
Account is defined more than once; use a unique name.
错误示例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Account,
Person
)
EDGE TABLES (
Account
SOURCE KEY(owner_id) REFERENCES Person
DESTINATION KEY(account_id) REFERENCES Account
);
建议的解决方法
为边定义使用一个唯一的名称。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Account,
Person
)
EDGE TABLES (
Account AS Owns
SOURCE KEY(owner_id) REFERENCES Person
DESTINATION KEY(account_id) REFERENCES Account
);
属性的标签定义必须保持一致
错误消息
The label Entity is defined with different property declarations. There is one
instance of this label defined with properties of [id]. Another instance is
defined with properties of [name].
错误示例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person LABEL Entity PROPERTIES (name),
Account LABEL Entity PROPERTIES (id)
);
建议的解决方法
您必须在同一标签下使用同一组属性名称。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person LABEL Entity PROPERTIES (id, name),
Account LABEL Entity PROPERTIES (id, name)
);
属性声明必须与属性类型保持一致
错误消息
The property declaration of name has type conflicts. There is an existing
declaration of type INT64. There is a conflicting one of type STRING.
错误示例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person PROPERTIES (name),
Account PROPERTIES (id AS name)
);
建议的解决方法
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person PROPERTIES (name),
Account PROPERTIES (CAST(id AS STRING) AS name)
);
属性定义不得是子查询
错误消息
Property value expression of count cannot contain a subquery.
错误示例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person PROPERTIES ((SELECT COUNT(*) FROM Person) AS count)
);
建议的解决方法
N/A。不允许这种情况。
同一元素定义中的属性定义必须一致
错误消息
Property location has more than one definition in the element table Person
错误示例
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person
LABEL Person PROPERTIES (country AS location)
LABEL Entity PROPERTIES (city AS location)
);
建议的解决方法
使用相同的媒体资源定义。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person
LABEL Person PROPERTIES (country AS location)
LABEL Entity PROPERTIES (country AS location)
);
或者,分配不同的属性名称。
CREATE OR REPLACE PROPERTY GRAPH FinGraph
NODE TABLES (
Person
LABEL Person PROPERTIES (country AS location)
LABEL Entity PROPERTIES (city AS city)
);
查询错误
查询结果基于设置和查询 Spanner Graph 中使用的相应数据集。
图表元素无法作为查询结果返回
错误消息
Returning expressions of type GRAPH_ELEMENT is not allowed
错误示例
GRAPH FinGraph
MATCH (n:Account)
RETURN n;
建议的解决方法
GRAPH FinGraph
MATCH (n:Account)
RETURN TO_JSON(n) AS n;
属性规范不能与 WHERE
子句搭配使用
错误消息
WHERE clause cannot be used together with property specification
错误示例
GRAPH FinGraph
MATCH (n:Account {id: 1} WHERE n.is_blocked)
RETURN n.id;
建议的解决方法
您可以使用以下某种建议的解决方法。
GRAPH FinGraph
MATCH (n:Account {id: 1})
WHERE n.is_blocked
RETURN n.id;
GRAPH FinGraph
MATCH (n:Account WHERE n.id = 1 AND n.is_blocked )
RETURN n.id;
GRAPH FinGraph
MATCH (n:Account {id: 1, is_blocked: TRUE})
RETURN n.id;
不允许引用之前语句中定义的变量
错误消息
Name 'account_id', defined in the previous statement, can only be referenced in
the outermost WHERE clause of MATCH
说明
MATCH
模式中不允许引用之前语句中定义的变量。在图查询中,之前语句定义的名称只能在 MATCH
的最外层 WHERE
子句中使用。
错误示例
GRAPH FinGraph
LET account_id = 1
MATCH (n:Account {id: account_id})
RETURN n.id;
建议的解决方法
GRAPH FinGraph
LET account_id = 1
MATCH (n:Account)
WHERE n.id = account_id
RETURN n.id;
不允许重新定义相关图表变量
错误消息
The name account is already defined; redefining graph element variables in a
subquery is not allowed. To refer to the same graph element, use a different
name and add an explicit filter that checks for equality.
说明
在图表查询中,无法在内部图表子查询中重新定义图表元素名称。此场景可能会被解读为引用与外部作用域相同的图元素,或绑定到会掩盖外部作用域名称的新图元素。不允许重新定义。
错误示例
GRAPH FinGraph
MATCH (account:Account)
RETURN account.id AS account_id, VALUE {
MATCH (account:Account)-[transfer:Transfers]->(:Account)
RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
建议的解决方法
GRAPH FinGraph
MATCH (account:Account)
RETURN account.id AS account_id, VALUE {
MATCH (a:Account)-[transfer:Transfers]->(:Account)
WHERE a = account
RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
查询语义问题
查询结果基于设置和查询 Spanner Graph 中使用的相应数据集。
不同的 WHERE
和 FILTER
会产生不同的输出
说明
FILTER
是语句;WHERE
是 MATCH
、OPTIONAL
MATCH
语句的一部分,属于子句。
在第一个示例中,WHERE
子句会向 OPTIONAL MATCH
语句中描述的模式添加其他约束条件。这不是匹配完成后的过滤条件。
在第二个示例中,FILTER
语句是匹配完成后的过滤条件。
示例问题
以下示例的输出不同,因为 WHERE
和 FILTER
不同。
示例 1
GRAPH FinGraph
MATCH (n:Account {id: 7})
OPTIONAL MATCH (m:Account)
WHERE FALSE
RETURN n.id AS n_id, m.id AS m_id;
n_id | m_id |
---|---|
7 | null |
示例 2
GRAPH FinGraph
MATCH (n:Account {id: 7})
OPTIONAL MATCH (m:Account)
FILTER FALSE
RETURN n.id AS n_id, m.id AS m_id;
空白结果。
在语句中传播不同的变量会导致不同的输出
说明
在图表查询语言中,多次声明的变量在所有出现位置都指同一图表元素。
在示例 1 中,没有 Account
节点的 id
同时为 7
和 16
。因此,系统会返回空结果。
在示例 2 中,前一个语句不会返回名称 n
(只会返回 id
)。因此,第二个 MATCH
会找到 id
为 16
的 Account
节点。
示例问题
以下示例的输出不同,因为不同的变量会传播到各个语句。
示例 1
GRAPH FinGraph
MATCH (n:Account {id: 7})
RETURN n
NEXT
MATCH (n:Account {id: 16})
RETURN n.id AS n_id;
空白结果。
示例 2
GRAPH FinGraph
MATCH (n:Account {id: 7})
RETURN n.id AS id
NEXT
MATCH (n:Account {id: 16})
RETURN n.id AS n_id;
n_id |
---|
16 |
如果后续语句不是 LIMIT
,系统会忽略 ORDER BY
说明
在图查询语言中,除非满足以下条件之一,否则系统会忽略 ORDER BY
语句:
ORDER BY
是最后一个语句。ORDER BY
紧随LIMIT
之后。
在示例 1 中,LIMIT
不是紧随 ORDER BY
之后;最后一个 LIMIT
是分开的。这意味着引擎会忽略 ORDER BY
。
在示例 2 中,ORDER BY
适用,因为 LIMIT
紧随 ORDER BY
之后。
示例问题
以下示例的输出不同,因为在示例 1 中,如果 ORDER BY
语句未与 LIMIT
搭配使用,系统会忽略该语句。
示例 1
GRAPH FinGraph
MATCH (n:Account)
ORDER BY n.id DESC
RETURN n.id
LIMIT 3;
n_id |
---|
7 |
示例 2
GRAPH FinGraph
MATCH (n:Account)
ORDER BY n.id DESC
LIMIT 3
RETURN n.id;
n_id |
---|
20 |
不同的边缘模式会产生不同的输出
说明
在错误示例中使用的数据集中,ANY
方向边缘模式会与图中的每个 Transfers
边缘匹配两次。
在示例 1 中,从 Account(id=x)
到 Account(id=y)
的 Transfers
边可以匹配两次,如下所示:
- n=
Account(id=x)
, m=Account(id=y)
- n=
Account(id=y)
, m=Account(id=x)
示例 2 中只有一个匹配,其中 n=Account(id=x)
且 m=Account(id=y)
。
因此,示例 1 中的查询会返回 10
,示例 2 中的查询会返回 5
。
示例问题
以下示例的输出不同,因为使用了不同的边缘模式。
示例 1
GRAPH FinGraph
MATCH (n:Account)-[:Transfers]-(m:Account)
RETURN COUNT(*) AS num_transfer_edges;
num_transfer_edges |
---|
10 |
示例 2
GRAPH FinGraph
MATCH (n:Account)-[:Transfers]->(m:Account)
RETURN COUNT(*) AS num_transfer_edges;
num_transfer_edges |
---|
5 |
更改错误
更新结果基于设置和查询 Spanner Graph 中使用的数据集。
缺少来源节点违反外键约束条件
错误消息
Parent row for row [...] in table AccountTransferAccount is missing. Row cannot
be written.
说明
AccountTransferAccount
边表是 INTERLEAVED INTO PARENT Account node
表。如需创建 Transfer
边,其父 Account
节点必须已存在。
错误示例
INSERT INTO AccountTransferAccount (id, to_id, create_time, amount)
VALUES (100, 1, PENDING_COMMIT_TIMESTAMP(), 200);
建议的解决方法
先创建前置的 Account
节点,然后创建 Transfer
边。
缺少目标节点违反外键约束条件
错误消息
Foreign key constraint FK_TransferTo is violated on table
AccountTransferAccount. Cannot find referenced values in Account(id)
说明
AccountTransferAccount
表通过名为 FK_TransferTo
的 ForeignKey
引用 Accounttable
。如需创建 Transfer
边,引用的尾随节点 Account
节点必须已存在。
错误示例
INSERT INTO AccountTransferAccount (id, to_id, create_time, amount)
VALUES (1, 100, PENDING_COMMIT_TIMESTAMP(), 200);
建议的解决方法
先创建尾随账号节点,然后创建 Transfer
边。
孤立的出边违反了父子关系
错误消息
Integrity constraint violation during DELETE/REPLACE. Found child row [...] in
table AccountTransferAccount
说明
AccountTransferAccount
边表是 INTERLEAVED INTO PARENT
Account
节点表,并且要删除的 Account
节点仍附有出边。
错误示例
DELETE FROM Account WHERE id = 1;
建议的解决方法
请先删除所有出站 Transfer
边,然后再删除 Account
节点。或者,为 INTERLEAVE
定义 ON DELETE CASCADE
,并让 Spanner 自动删除这些边。
孤立的入边违反了父子关系
错误消息
Foreign key constraint violation when deleting or updating referenced row(s):
referencing row(s) found in table AccountTransferAccount
说明
AccountTransferAccount
边表通过 ForeignKey
引用 Account
节点表,并且要删除的 Account
节点仍附有入边。
错误示例
DELETE FROM Account WHERE id = 1;
建议的解决方法
请先删除所有传入的 Transfer
边,然后再删除 Account
节点。或者,为 ForeignKey
定义 ON DELETE CASCADE
,并让 Spanner 自动删除这些边。