Spanner Graph 문제 해결

이 문서에서는 Spanner Graph를 사용할 때 발생할 수 있는 오류를 설명합니다. 오류의 예시와 권장 해결 방법도 제공됩니다.

이 문제 해결 가이드를 검토한 후에도 추가 지원이 필요한 경우 지원 받기를 참조하세요.

스키마 오류

스키마 결과는 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)
  );

해당 사항 없음. 이 조건은 허용되지 않습니다.

속성 정의가 동일한 요소 정의 내에서 일치해야 함

오류 메시지

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 설정 및 쿼리에서 사용된 데이터 세트를 기반으로 합니다.

WHEREFILTER가 다르면 출력도 달라짐

설명

FILTER는 문입니다. WHEREMATCH, OPTIONAL MATCH 문에 포함된 절입니다.

첫 번째 예시에서 WHERE 절은 OPTIONAL MATCH 문에 설명된 패턴에 추가 제약 조건을 추가합니다. 일치가 완료된 후에는 필터가 아닙니다.

두 번째 예시에서 FILTER 문은 일치가 완료된 후의 필터입니다.

문제 예시

다음 예시에서는 WHEREFILTER가 다르므로 출력이 다릅니다.

예시 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에서는 id716Account 노드가 없습니다. 따라서 빈 결과가 반환됩니다.

예시 2에서 이름 n은 이전 문에서 반환되지 않습니다(id만 반환됨). 따라서 두 번째 MATCHid16Account 노드를 찾습니다.

문제 예시

다음 예시에서는 문이 여러 개 있으므로 서로 다른 변수가 전파되어 출력이 다릅니다.

예시 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 문은 다음 중 하나가 true인 경우를 제외하고 무시됩니다.

  • ORDER BY는 마지막 문입니다.
  • ORDER BY 바로 다음에 LIMIT가 옵니다.

예시 1에서 LIMITORDER BY 바로 뒤에 있지 않습니다. 마지막 LIMIT가 떨어져 있습니다. 이는 엔진에서 ORDER BY를 무시한다는 의미입니다.

예시 2에서는 LIMITORDER BY 바로 뒤에 있으므로 ORDER BY를 적용할 수 있습니다.

문제 예시

다음 예시에서는 예시 1에서 LIMIT 없이 ORDER BY 문이 사용되면 무시되므로 출력이 다릅니다.

예시 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 노드를 삭제합니다. 또는 INTERLEAVEON 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 노드를 삭제합니다. 또는 ForeignKeyON DELETE CASCADE를 정의하고 Spanner에서 이러한 에지를 자동으로 삭제하도록 합니다.