פתרון בעיות ב-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. בשאילתת הגרף, אפשר להשתמש בשמות שהוגדרו בהצהרות קודמות רק בסעיף WHERE החיצוני ביותר של MATCH.

דוגמה לשגיאה
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 מוצאת את הצומת Account שהמאפיין id שלו הוא 16.

בעיה לדוגמה

בדוגמאות הבאות יש פלטים שונים כי משתנים שונים מועברים בין ההצהרות.

דוגמה 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

המערכת מתעלמת מהערך ORDER BY אם יש הצהרה עוקבת שהיא לא LIMIT

תיאור

בשפת השאילתות של הגרף, המערכת מתעלמת מההצהרה ORDER BY אלא אם מתקיים אחד מהתנאים הבאים:

  • ORDER BY היא ההצהרה האחרונה.
  • ORDER BY מופיע מיד אחרי LIMIT.

בדוגמה 1, התו LIMIT לא מופיע מיד אחרי ORDER BY, והתו LIMIT האחרון מופיע בנפרד. המשמעות היא שהמנוע מתעלם מ-ORDER BY.

בדוגמה 2, התנאי ORDER BY מתקיים כי LIMIT מופיע מיד אחרי ORDER BY.

בעיה לדוגמה

בדוגמאות הבאות יש פלטים שונים כי ההצהרה ORDER BY מוזנחת כשמשתמשים בה בלי LIMIT בדוגמה 1.

דוגמה 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, אפשר להתאים פעמיים את קצה Transfers מ-Account(id=x) ל-Account(id=y), באופן הבא:

  • 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 edge table is INTERLEAVED INTO PARENT Account node table. כדי ליצור את הקצה 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 מתייחסת אל Accounttable באמצעות ForeignKey שנקרא FK_TransferTo. כדי ליצור את קצה 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 edge table היא INTERLEAVED INTO PARENT Account node table וה-Account node שרוצים למחוק עדיין כולל קצוות יוצאים שמחוברים אליו.

דוגמה לשגיאה

DELETE FROM Account WHERE id = 1;

קודם מוחקים את כל הקצוות היוצאים Transfer ואז מוחקים את הצומת Account. לחלופין, אפשר להגדיר את ON DELETE CASCADE עבור INTERLEAVE ולתת ל-Spanner למחוק אוטומטית את הקצוות האלה.

קצה יתום של קו שמגיע מחוץ ל-VPC מפר את הקשר בין רשתות הורה וצאצא

הודעת השגיאה

Foreign key constraint violation when deleting or updating referenced row(s): referencing row(s) found in table AccountTransferAccount

תיאור

טבלת הקצוות AccountTransferAccount מפנה לטבלת הצמתים Account דרך ForeignKey, ולצומת Account שרוצים למחוק עדיין יש קצוות נכנסים שמחוברים אליו.

דוגמה לשגיאה

DELETE FROM Account WHERE id = 1;

קודם מוחקים את כל הקשתות הנכנסות Transfer ואז מוחקים את הצומת Account. לחלופין, אפשר להגדיר ON DELETE CASCADE עבור ForeignKey ולתת ל-Spanner למחוק את הקצוות האלה באופן אוטומטי.