このドキュメントでは、Spanner Graph の使用時に発生する可能性のあるエラーについて説明します。エラーの例と推奨される修正方法も示されます。
スキーマのエラー
スキーマの結果は、Spanner グラフを設定してクエリを実行するで使用したデータセットに基づいています。
要素キーは一意である必要があります
エラー メッセージ
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)
);
推奨する修正
なし。この条件は許可されません。
プロパティの定義は、同じ要素定義内で一貫している必要があります
エラー メッセージ
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
ステートメントに記載されているパターンに制約を追加しています。これは、マッチングが完了した後のフィルタではありません。
2 番目の例では、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 では、id
が 7
と 16
の両方の Account
ノードはありません。このため、空の結果が返されます。
例 2 では、前のステートメントから名前 n
が返されません(id
のみが返されます)。したがって、2 番目の 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 では、LIMIT
が ORDER BY
の直後に続くため、ORDER BY
が適用されます。
問題の例
以下の例では、出力が異なるため、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
エッジと 2 回一致しています。
例 1 では、Account(id=x)
から Account(id=y)
への Transfers
エッジが、次のように 2 回一致できます。
- 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 つだけです。
その結果、例 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);
推奨する修正
最初に末尾の Account ノードを作成し、次に 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 でエッジを自動的に削除します。