iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0

在[Day03]~[Day06],我們將使用下面這個schema幫助我們熟悉EdgeDB的基本操作。

type User {
    required name: str;
    multi followers: User;
}

type Article {
    required title: str;
    required author: User;
}

這個schema內定義了:

  • User object type

    • 內含一個名為「"name"」的property,且為requiredsingle,即每次insert時都要提供一個str型態。
    • 內含一個名為「"followers"」的link,且為optionalmulti,即每次insert時不一定要提供;但如果有提供的話,可以包含一個以上的User object
  • Article object type

    • 內含一個名為「"title"」的property,且為requiredsingle,即每次insert時都要提供一個str型態。
    • 內含一個名為「"author"」的link,且為requiredsingle,即每次insert時都要提供一個User object

Insert

insert可以幫助我們建立object。在EdgeDB中關鍵字是case insensitive,所以insertInSeRt會被視為是相同的。在傳統SQL中,很多人都習慣將關鍵字大寫,但在EdgeQL的官方文件中,關鍵字皆以小寫呈現。我自己是習慣寫成小寫,但大家可以依照自己的喜好來選擇,我相信只要寫法是一致的,閱讀起來應該都不會太困難。

以下我將以CathyJohnTomJeff來簡單稱呼其name property分別為「"Cathy"」、「"John"」、「"Tom"」與「"Jeff"」的User object

假設我們想建立John,可以使用insert搭配shape(即{})來做:

insert User {name:= "John"};

這邊有兩點需要注意:

  • 指定propertylink時需使用:=
  • query須以;作為結束。

接著我們建立一個Article object,其title property為「"first article"」,author linkJohn

insert Article {
     title:= "first article",
     author:= assert_single(User)
};

目前我們只有John一個User object,所以我們可以「取巧」以User代替,而不必真的選取到John。由於authorsingle link,所以必須使用assert_single()來確定其返回結果不會多於一個(如果沒有使用assert_single()或返回結果多於一個的話,都會報錯)。assert_single()是一個funtion,可以說是EdgeDB最常使用的保護措施之一,剛開始可能會覺得不太習慣,但這就像是另類的型別檢查一樣,雖然一開始要多花點功夫,但卻可以避免後面可能生的一連串錯誤。

Nested inserts

由於像上述這樣的情況相當常見,我們一般會使用下面這種query:

insert Article {
   title:= "first article",
   author:= (insert User {name:= "John"})
};

由於insert的返回結果必定是一個或以下,所以這邊可以不用加上assert_single()。但如果改寫為下面這樣,也是正確的寫法:

insert Article {
   title:= "first article",
   author:= assert_single((insert User {name:= "John"}))
};

請注意assert_single()內需要使用括號,不可省略。如果寫成下面這樣:

❌
insert Article {
   title:= "first article",
   author:= assert_single(insert User {name:= "John"})
};

EdgeDB會報錯:

error: EdgeQLSyntaxError: Missing parentheses around statement used as an expression

Bulk inserts

Bulk inserts是使用for-loop來同時生成大量的object。例如,我們想同時生成JeffTomCathy的話,可以這麼寫:

for name in {"Jeff", "Tom", "Cathy"}
union (insert User {name:= name});

其中union為EdgeDB連接兩個EdgeDBSet的運算子。

值得一提的是,在EdgeDBv5之後,union變成可省略的關鍵字,也就是說上述query也可以寫成:

for name in {"Jeff", "Tom", "Cathy"}
insert User {name:= name};

如果將union寫出來,可以更加表現出所有的query結果都是EdgeDBSet;但是省略union的確可以讓語法更簡潔,也更像一般程式中的for-loop,大家可以自己選擇喜歡的寫法。


上一篇
[Day02] - EdgeDB概述
下一篇
[Day04] - 如何select
系列文
一起看無間道學EdgeDB30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言