Firebase SQL Connect ช่วยให้คุณสร้างเครื่องมือเชื่อมต่อสำหรับอินสแตนซ์ PostgreSQL ที่จัดการด้วย Cloud SQL ได้ เครื่องมือเชื่อมต่อเหล่านี้เป็นการผสมผสานระหว่างการค้นหาและการเปลี่ยนแปลงเพื่อใช้ข้อมูลจากสคีมา
คู่มือเริ่มต้นใช้งานได้แนะนำสคีมาแอปรีวิวภาพยนตร์ สำหรับ PostgreSQL
นอกจากนี้ คู่มือดังกล่าวยังได้แนะนำการดำเนินการดูแลระบบทั้งแบบที่ติดตั้งใช้งานได้และแบบเฉพาะกิจ ซึ่งรวมถึงการเปลี่ยนแปลง
- การเปลี่ยนแปลงที่ติดตั้งใช้งานได้ คือการเปลี่ยนแปลงที่คุณติดตั้งใช้งานเพื่อเรียกจากแอปไคลเอ็นต์ในเครื่องมือเชื่อมต่อ โดยมีปลายทาง API ที่คุณกำหนด SQL Connect จะผสานรวม การตรวจสอบสิทธิ์และการให้สิทธิ์เข้าถึงในการเปลี่ยนแปลงเหล่านี้ และสร้าง SDK ของไคลเอ็นต์ ตาม API ของคุณ
- การเปลี่ยนแปลงด้านการดูแลระบบแบบเฉพาะกิจ จะทำงานจากสภาพแวดล้อมที่มีสิทธิ์เพื่อกรอกข้อมูลและจัดการตาราง คุณสามารถสร้างและดำเนินการการเปลี่ยนแปลงเหล่านี้ใน Firebaseคอนโซล จากสภาพแวดล้อมที่มีสิทธิ์โดยใช้Firebase Admin SDKและในสภาพแวดล้อมการพัฒนาในเครื่องโดยใช้ ส่วนขยาย SQL Connect VS Code
คู่มือนี้จะเจาะลึกการเปลี่ยนแปลงที่ติดตั้งใช้งานได้
ฟีเจอร์ของการเปลี่ยนแปลง SQL Connect
SQL Connect ช่วยให้คุณทำการเปลี่ยนแปลงพื้นฐานได้ทุกวิธี ตามที่คุณคาดหวังจากฐานข้อมูล PostgreSQL ดังนี้
- ดำเนินการ CRUD
- จัดการการดำเนินการหลายขั้นตอนด้วยธุรกรรม
แต่ด้วยส่วนขยายของ SQL Connect สำหรับ GraphQL คุณสามารถติดตั้งใช้งาน การเปลี่ยนแปลงขั้นสูงสำหรับแอปที่เร็วขึ้นและมีประสิทธิภาพมากขึ้นได้ ดังนี้
- ใช้สเกลาร์คีย์ ที่การดำเนินการหลายอย่างแสดงผลเพื่อลดความซับซ้อนของการดำเนินการซ้ำๆ ในระเบียน
- ใช้ค่าเซิร์ฟเวอร์ เพื่อกรอกข้อมูลด้วยการดำเนินการที่เซิร์ฟเวอร์ให้ไว้
- ทำการค้นหาระหว่างการดำเนินการเปลี่ยนแปลงหลายขั้นตอนเพื่อค้นหาข้อมูล ซึ่งช่วยประหยัดบรรทัดโค้ดและการเดินทางไปกลับไปยังเซิร์ฟเวอร์
ใช้ฟิลด์ที่สร้างขึ้นเพื่อติดตั้งใช้งานการเปลี่ยนแปลง
การดำเนินการ SQL Connect จะขยายชุดฟิลด์ ที่ SQL Connect สร้างขึ้นโดยอัตโนมัติตามประเภทและความสัมพันธ์ของประเภท ในสคีมา เครื่องมือในเครื่องจะสร้างฟิลด์เหล่านี้ขึ้นทุกครั้งที่คุณแก้ไขสคีมา
คุณสามารถใช้ฟิลด์ที่สร้างขึ้นเพื่อติดตั้งใช้งานการเปลี่ยนแปลงได้ ตั้งแต่การสร้าง อัปเดต และลบระเบียนแต่ละรายการในตารางเดียว ไปจนถึงการอัปเดตหลายตารางที่ซับซ้อนมากขึ้นสมมติว่าสคีมามีประเภท Movie และประเภท Actor ที่เชื่อมโยงกัน
SQL Connect จะสร้างฟิลด์ movie_insert,
movie_update, movie_delete และอื่นๆ
การเปลี่ยนแปลงด้วยฟิลด์
movie_insert
|
ฟิลด์ |
ใช้ฟิลด์นี้เพื่อสร้างภาพยนตร์เรื่องเดียว mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) { movie_insert(data: { title: $title releaseYear: $releaseYear genre: $genre rating: $rating }) } |
การเปลี่ยนแปลงด้วยฟิลด์
movie_update
|
ฟิลด์ |
ใช้ฟิลด์นี้เพื่ออัปเดตภาพยนตร์เรื่องเดียวด้วยคีย์ mutation UpdateMovie($myKey: Movie_Key!, $genre: String, $rating: Int, $description: String) { movie_update(key: $myKey, data: { genre: $genre rating: $rating description: $description }) } |
การเปลี่ยนแปลงด้วยฟิลด์
movie_delete
|
ฟิลด์ |
ใช้ฟิลด์นี้เพื่อลบภาพยนตร์เรื่องเดียวด้วยคีย์ mutation DeleteMovie($myKey: Movie_Key!) { movie_delete(key: $myKey) { key } } |
องค์ประกอบสำคัญของการเปลี่ยนแปลง
SQL Connect การเปลี่ยนแปลงคือการเปลี่ยนแปลง GraphQL ที่มี SQL Connect ส่วนขยาย เช่นเดียวกับการเปลี่ยนแปลง GraphQL ปกติ คุณสามารถกำหนดชื่อการดำเนินการและรายการตัวแปร GraphQL ได้
SQL Connect ขยายการค้นหา GraphQL ด้วยคำสั่ง ที่กำหนดเอง เช่น
@auth และ @transaction
ดังนั้นการเปลี่ยนแปลงต่อไปนี้จึงมีองค์ประกอบดังนี้
- คำจำกัดความประเภท
mutation - ชื่อการดำเนินการ (การเปลี่ยนแปลง)
SignUp - อาร์กิวเมนต์การดำเนินการตัวแปรเดียว
$username - คำสั่งเดียว
@auth - ฟิลด์เดียว
user_insert
mutation SignUp($username: String!) @auth(level: USER) {
user_insert(data: {
id_expr: "auth.uid"
username: $username
})
}
อาร์กิวเมนต์การเปลี่ยนแปลงทุกรายการต้องมีการประกาศประเภท ซึ่งอาจเป็นประเภทในตัว เช่น String หรือประเภทที่กำหนดโดยสคีมาที่กำหนดเอง เช่น Movie
เขียนการเปลี่ยนแปลงพื้นฐาน
คุณสามารถเริ่มเขียนการเปลี่ยนแปลงเพื่อสร้าง อัปเดต และลบระเบียนแต่ละรายการจากฐานข้อมูลได้
สร้าง
มาสร้างพื้นฐานกัน
# Create a movie based on user input
mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
movie_insert(data: {
title: $title
releaseYear: $releaseYear
genre: $genre
rating: $rating
})
}
# Create a movie with default values
mutation CreateMovie2 {
movie_insert(data: {
title: "Sherlock Holmes"
releaseYear: 2009
genre: "Mystery"
rating: 5
})
}
หรือ upsert
# Movie upsert using combination of variables and literals
mutation UpsertMovie($title: String!) {
movie_upsert(data: {
title: $title
releaseYear: 2009
genre: "Mystery"
rating: 5
genre: "Mystery/Thriller"
})
}
ทำการอัปเดต
ตัวอย่างการอัปเดต โปรดิวเซอร์และผู้กำกับหวังว่าคะแนนเฉลี่ยเหล่านั้นจะเป็นไปตามเทรนด์
ฟิลด์ movie_update มีอาร์กิวเมนต์ id ที่คาดไว้เพื่อระบุระเบียนและฟิลด์ data ที่คุณใช้เพื่อตั้งค่าในการอัปเดตนี้ได้
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id,
data: {
genre: $genre
rating: $rating
description: $description
})
}
หากต้องการทำการอัปเดตหลายรายการ ให้ใช้ฟิลด์ movie_updateMany
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $rating: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
data:
{
rating: $rating
})
}
ใช้การดำเนินการเพิ่ม ลด ผนวก และนำหน้าด้วย _update
แม้ว่าในการเปลี่ยนแปลง _update และ _updateMany คุณจะตั้งค่าใน
data: ได้อย่างชัดเจน แต่การใช้โอเปอเรเตอร์ เช่น เพิ่ม เพื่ออัปเดต
ค่ามักจะสมเหตุสมผลกว่า
หากต้องการแก้ไขตัวอย่างการอัปเดตก่อนหน้านี้ ให้สมมติว่าคุณต้องการเพิ่มคะแนนของภาพยนตร์เรื่องหนึ่ง คุณสามารถใช้ไวยากรณ์ rating_update กับโอเปอเรเตอร์ inc ได้
mutation UpdateMovie(
$id: UUID!,
$ratingIncrement: Int!
) {
movie_update(id: $id, data: {
rating_update: {
inc: $ratingIncrement
}
})
}
SQL Connect รองรับโอเปอเรเตอร์ต่อไปนี้สำหรับการอัปเดตฟิลด์
incเพื่อเพิ่มประเภทข้อมูลInt,Int64,Float,DateและTimestampdecเพื่อลดประเภทข้อมูลInt,Int64,Float,DateและTimestamp
สำหรับรายการ คุณยังอัปเดตด้วยค่าแต่ละค่าหรือรายการค่าได้โดยใช้โอเปอเรเตอร์ต่อไปนี้
addเพื่อผนวกรายการหากรายการนั้นยังไม่ได้อยู่ในประเภทรายการ ยกเว้นรายการเวกเตอร์removeเพื่อนำรายการทั้งหมดออกจากประเภทรายการ หากมี ยกเว้นรายการเวกเตอร์appendเพื่อผนวกรายการลงในประเภทรายการ ยกเว้นรายการเวกเตอร์prependเพื่อนำหน้ารายการลงในประเภทรายการ ยกเว้นรายการเวกเตอร์
ทำการลบ
แน่นอนว่าคุณสามารถลบข้อมูลภาพยนตร์ได้ นักอนุรักษ์ภาพยนตร์จะต้องการเก็บรักษาภาพยนตร์จริงไว้ให้นานที่สุด
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
คุณสามารถใช้ _deleteMany ได้ที่นี่
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
เขียนการเปลี่ยนแปลงในความสัมพันธ์
ดูวิธีใช้การเปลี่ยนแปลง _upsert โดยนัยในความสัมพันธ์
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
ออกแบบสคีมาสำหรับการเปลี่ยนแปลงที่มีประสิทธิภาพ
SQL Connect มีฟีเจอร์สำคัญ 2 อย่างที่ช่วยให้คุณ เขียนการเปลี่ยนแปลงได้อย่างมีประสิทธิภาพมากขึ้นและประหยัดการดำเนินการไปกลับ
สเกลาร์คีย์ คือตัวระบุออบเจ็กต์ที่กระชับซึ่ง SQL Connect ประกอบขึ้นโดยอัตโนมัติจากฟิลด์คีย์ในสคีมา สเกลาร์คีย์ช่วยให้คุณค้นหาข้อมูลเกี่ยวกับข้อมูลประจำตัวและโครงสร้างของข้อมูลได้ในการเรียกครั้งเดียว ซึ่งช่วยเพิ่มประสิทธิภาพ สเกลาร์คีย์มีประโยชน์อย่างยิ่งเมื่อคุณต้องการดำเนินการตามลำดับกับระเบียนใหม่และต้องมีตัวระบุที่ไม่ซ้ำกันเพื่อส่งไปยังการดำเนินการที่จะเกิดขึ้น รวมถึงเมื่อคุณต้องการเข้าถึงคีย์เชิงสัมพันธ์เพื่อดำเนินการที่ซับซ้อนมากขึ้น
การใช้ค่าเซิร์ฟเวอร์ ช่วยให้คุณให้เซิร์ฟเวอร์กรอก
ฟิลด์ในตารางแบบไดนามิกได้อย่างมีประสิทธิภาพโดยใช้ค่าที่เก็บไว้หรือค่าที่คำนวณได้ง่ายตาม
นิพจน์ CEL ฝั่งเซิร์ฟเวอร์ที่เฉพาะเจาะจงในอาร์กิวเมนต์ expr ตัวอย่างเช่น คุณ
สามารถกำหนดฟิลด์ที่มีการประทับเวลาเมื่อเข้าถึงฟิลด์โดยใช้
เวลาที่เก็บไว้ในคำขอการดำเนินการ updatedAt: Timestamp!
@default(expr: "request.time")
เขียนการเปลี่ยนแปลงขั้นสูง: ให้ SQL Connect ระบุค่าโดยใช้ field_expr ไวยากรณ์
ตามที่กล่าวไว้ในหัวข้อสเกลาร์คีย์และค่าเซิร์ฟเวอร์
คุณสามารถออกแบบสคีมาเพื่อให้เซิร์ฟเวอร์กรอกค่าสำหรับฟิลด์ทั่วไป
เช่น ids และวันที่ เพื่อตอบสนองต่อคำขอของไคลเอ็นต์
นอกจากนี้ คุณยังใช้ข้อมูล เช่น รหัสผู้ใช้ ที่ส่งใน
SQL Connect request จากแอปไคลเอ็นต์ได้ด้วย
เมื่อติดตั้งใช้งานการเปลี่ยนแปลง ให้ใช้ไวยากรณ์ field_expr เพื่อทริกเกอร์การอัปเดตที่เซิร์ฟเวอร์สร้างขึ้นหรือเข้าถึงข้อมูลจากคำขอ ตัวอย่างเช่น หากต้องการส่ง
การให้สิทธิ์เข้าถึง uid ที่เก็บไว้ในคำขอไปยังการดำเนินการ _upsert ให้ส่ง
"auth.uid" ในฟิลด์ userId_expr
# Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}
# Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}
หรือในแอปรายการสิ่งที่ต้องทำที่คุ้นเคย เมื่อสร้างรายการสิ่งที่ต้องทำใหม่ คุณสามารถส่ง id_expr เพื่อสั่งให้เซิร์ฟเวอร์สร้าง UUID สำหรับรายการโดยอัตโนมัติ
mutation CreateTodoListWithFirstItem(
$listName: String!
) @transaction {
# Step 1
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
}
ดูข้อมูลเพิ่มเติมได้ที่สเกลาร์ _Expr ใน
เอกสารอ้างอิงสเกลาร์
เขียนการเปลี่ยนแปลงขั้นสูง: การดำเนินการหลายขั้นตอน
มีหลายสถานการณ์ที่คุณอาจต้องการรวมฟิลด์การเขียนหลายรายการ (เช่น การแทรก) ไว้ในการเปลี่ยนแปลงเดียว นอกจากนี้ คุณยังอาจต้องการอ่านฐานข้อมูลระหว่างการดำเนินการการเปลี่ยนแปลงเพื่อค้นหาและยืนยันข้อมูลที่มีอยู่ก่อนที่จะดำเนินการ เช่น การแทรกหรือการอัปเดต ตัวเลือกเหล่านี้ช่วยประหยัดการดำเนินการไปกลับและค่าใช้จ่าย
SQL Connect ช่วยให้คุณดำเนินการตรรกะหลายขั้นตอนในการเปลี่ยนแปลงได้โดย รองรับสิ่งต่อไปนี้
ฟิลด์การเขียนหลายรายการ
ฟิลด์การอ่านหลายรายการในการเปลี่ยนแปลง (โดยใช้คีย์เวิร์ดฟิลด์
query)คำสั่ง
@transactionซึ่งรองรับ ธุรกรรมที่คุ้นเคยจากฐานข้อมูลเชิงสัมพันธ์คำสั่ง
@checkซึ่งช่วยให้ คุณประเมินเนื้อหาของการอ่านโดยใช้นิพจน์ CEL และดำเนินการต่อไปนี้ตามผลการประเมิน- ดำเนินการสร้าง อัปเดต และลบที่กำหนดโดยการเปลี่ยนแปลง
- ดำเนินการแสดงผลลัพธ์ของฟิลด์การค้นหา
- ใช้ข้อความที่แสดงผลเพื่อดำเนินการตรรกะที่เหมาะสมในโค้ดไคลเอ็นต์
คำสั่ง
@redactซึ่งช่วยให้คุณละเว้น ผลลัพธ์ของฟิลด์การค้นหาจากผลลัพธ์โปรโตคอลแบบมีสายการผูก
responseของ CEL ซึ่งเก็บผลลัพธ์สะสมของการเปลี่ยนแปลงและการค้นหาทั้งหมดที่ดำเนินการในการดำเนินการที่ซับซ้อนและมีหลายขั้นตอน คุณสามารถเข้าถึงการผูกresponseได้ดังนี้- ในคำสั่ง
@checkผ่านอาร์กิวเมนต์expr: - ด้วยค่าเซิร์ฟเวอร์ โดยใช้ไวยากรณ์
field_expr
- ในคำสั่ง
คำสั่ง @transaction
การรองรับการเปลี่ยนแปลงหลายขั้นตอนรวมถึงการจัดการข้อผิดพลาดโดยใช้ธุรกรรม
คำสั่ง @transaction บังคับให้การเปลี่ยนแปลงที่มีฟิลด์การเขียนเดียว (เช่น _insert หรือ _update) หรือมีฟิลด์การเขียนหลายรายการทำงานในธุรกรรมฐานข้อมูลเสมอ
การเปลี่ยนแปลงที่ไม่มี
@transactionจะดำเนินการฟิลด์รูทแต่ละรายการทีละรายการตามลำดับ การดำเนินการจะแสดงข้อผิดพลาดเป็นข้อผิดพลาดของฟิลด์บางส่วน แต่จะไม่แสดงผลกระทบของการดำเนินการที่ตามมาการเปลี่ยนแปลงที่มี
@transactionจะสำเร็จทั้งหมดหรือล้มเหลวทั้งหมด หากฟิลด์ใดฟิลด์หนึ่งภายในธุรกรรมล้มเหลว ระบบจะย้อนกลับธุรกรรมทั้งหมด
คำสั่ง @check และ @redact
คำสั่ง @check จะยืนยันว่าฟิลด์ที่ระบุมีอยู่ในผลการค้นหา ระบบจะใช้นิพจน์ Common Expression Language (CEL) เพื่อทดสอบค่าฟิลด์ ลักษณะการทำงานเริ่มต้นของคำสั่งคือการตรวจสอบและปฏิเสธโหนดที่มีค่าเป็น null หรือ [] (รายการว่าง)
คำสั่ง @redact จะปกปิดส่วนหนึ่งของการตอบกลับจากไคลเอ็นต์ ระบบจะยังคงประเมินฟิลด์ที่ปกปิดเพื่อดูผลข้างเคียง (รวมถึงการเปลี่ยนแปลงข้อมูลและ @check) และขั้นตอนต่อๆ ไปในนิพจน์ CEL จะยังคงเข้าถึงผลลัพธ์ได้
ใช้ @check, @check(message:) และ @redact
การใช้งานหลักของ @check และ @redact คือการค้นหาข้อมูลที่เกี่ยวข้องเพื่อตัดสินใจว่าจะให้สิทธิ์การดำเนินการบางอย่างหรือไม่ โดยใช้การค้นหาในตรรกะแต่ซ่อนการค้นหาจากไคลเอ็นต์ การค้นหาอาจแสดงข้อความที่เป็นประโยชน์สำหรับการจัดการที่ถูกต้องในโค้ดไคลเอ็นต์
query GetMovieEditors($movieId: UUID!) @auth(level: USER) {
moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
}
moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
user {
id
username
}
}
}
หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับคำสั่ง @check และ @redact ในการตรวจสอบการให้สิทธิ์เข้าถึง
โปรดดูการสนทนาเกี่ยวกับการค้นหาข้อมูลการให้สิทธิ์เข้าถึง
ใช้ @check เพื่อตรวจสอบคีย์
ฟิลด์การเปลี่ยนแปลงบางรายการ เช่น _update อาจไม่มีการดำเนินการใดๆ หากไม่มีระเบียนที่มีคีย์ที่ระบุ ในทำนองเดียวกัน การค้นหาอาจแสดงผลเป็น null หรือรายการว่าง ระบบจะไม่ถือว่าสิ่งเหล่านี้เป็นข้อผิดพลาดและจะไม่ทริกเกอร์การย้อนกลับ
หากต้องการป้องกันผลลัพธ์นี้ ให้ทดสอบว่าพบคีย์ได้หรือไม่โดยใช้คำสั่ง @check
# Delete by key, error if not found
mutation MustDeleteMovie($id: UUID!) @transaction {
movie_delete(id: $id) @check(expr: "this != null", message: "Movie not found, therefore nothing is deleted")
}
ใช้การผูก response เพื่อเชื่อมโยงการเปลี่ยนแปลงหลายขั้นตอน
แนวทางพื้นฐานในการสร้างระเบียนที่เกี่ยวข้อง เช่น Movie และ
รายการ MovieMetadata ที่เชื่อมโยงกัน มีดังนี้
- เรียกการเปลี่ยนแปลง
_insertสำหรับMovie - จัดเก็บคีย์ที่แสดงผลของภาพยนตร์ที่สร้างขึ้น
- จากนั้นเรียกการเปลี่ยนแปลง
_insertครั้งที่ 2 เพื่อสร้างระเบียนMovieMetadata
แต่ด้วย SQL Connect คุณสามารถจัดการกรณีทั่วไปนี้ได้ในการดำเนินการหลายขั้นตอนเดียวโดยเข้าถึง ผลลัพธ์ ของ _insert ครั้งแรกใน
_insert ครั้งที่ 2
การสร้างแอปรีวิวภาพยนตร์ที่ประสบความสำเร็จต้องใช้ความพยายามอย่างมาก มาติดตามรายการสิ่งที่ต้องทำด้วยตัวอย่างใหม่กัน
ใช้ response เพื่อตั้งค่าฟิลด์ด้วยค่าเซิร์ฟเวอร์
ในการเปลี่ยนแปลงรายการสิ่งที่ต้องทำต่อไปนี้
- การผูก
responseแสดงถึงออบเจ็กต์การตอบกลับบางส่วนจนถึงตอนนี้ ซึ่งรวมถึงฟิลด์การเปลี่ยนแปลงระดับบนสุดทั้งหมดก่อนฟิลด์ปัจจุบัน - ระบบจะเข้าถึงผลลัพธ์ของการดำเนินการ
todoList_insertเริ่มต้น ซึ่งแสดงผลid(คีย์) ในภายหลังในresponse.todoList_insert.idเพื่อให้เรา แทรกรายการสิ่งที่ต้องทำใหม่ได้ทันที
mutation CreateTodoListWithFirstItem(
$listName: String!,
$itemContent: String!
) @transaction {
# Sub-step 1:
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
# Sub-step 2:
todo_insert(data: {
listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
content: $itemContent,
})
}
ใช้ response เพื่อตรวจสอบฟิลด์โดยใช้ @check
response ยังใช้ได้ใน @check(expr: "...") ด้วย ดังนั้นคุณจึงใช้
สร้างตรรกะฝั่งเซิร์ฟเวอร์ที่ซับซ้อนยิ่งขึ้นได้ เมื่อรวมกับขั้นตอน query { … } ในการเปลี่ยนแปลง คุณจะทำสิ่งต่างๆ ได้มากขึ้นโดยไม่ต้องมีการเดินทางไปกลับระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์เพิ่มเติม
ในตัวอย่างต่อไปนี้ โปรดทราบว่า @check มีสิทธิ์เข้าถึง response.query อยู่แล้ว เนื่องจาก @check จะทำงานหลังขั้นตอนที่แนบอยู่เสมอ
mutation CreateTodoInNamedList(
$listName: String!,
$itemContent: String!
) @transaction {
# Sub-step 1: Look up List.id by its name
query
@check(expr: "response.query.todoLists.size() > 0", message: "No such TodoList with the name!")
@check(expr: "response.query.todoLists.size() < 2", message: "Ambiguous listName!") {
todoLists(where: { name: $listName }) {
id
}
}
# Sub-step 2:
todo_insert(data: {
listId_expr: "response.todoLists[0].id" # <-- Now we have the parent list ID to insert to
content: $itemContent,
})
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับการผูก response ได้ใน
เอกสารอ้างอิง CEL
ทำความเข้าใจการดำเนินการที่ถูกขัดจังหวะด้วย @transaction และ query @check
การเปลี่ยนแปลงหลายขั้นตอนอาจพบข้อผิดพลาดต่อไปนี้
- การดำเนินการฐานข้อมูลอาจล้มเหลว
- ตรรกะ `query
@check` อาจยุติการดำเนินการ
SQL Connect ขอแนะนำให้คุณใช้คำสั่ง @transaction กับ
การเปลี่ยนแปลงหลายขั้นตอน ซึ่งจะทำให้ฐานข้อมูลและผลลัพธ์การเปลี่ยนแปลงมีความสอดคล้องกันมากขึ้นและจัดการได้ง่ายขึ้นในโค้ดไคลเอ็นต์ ดังนี้
- เมื่อเกิดข้อผิดพลาดแรกหรือ
@checkล้มเหลว การดำเนินการจะสิ้นสุดลง ดังนั้นจึงไม่จำเป็นต้องจัดการการดำเนินการของฟิลด์ที่ตามมาหรือการประเมิน CEL - ระบบจะย้อนกลับเพื่อตอบสนองต่อข้อผิดพลาดของฐานข้อมูลหรือตรรกะ
@checkซึ่งทำให้ฐานข้อมูลอยู่ในสถานะที่สอดคล้องกัน - ระบบจะแสดงข้อผิดพลาดในการย้อนกลับไปยังโค้ดไคลเอ็นต์เสมอ
อาจมีกรณีการใช้งานบางกรณีที่คุณเลือกที่จะไม่ใช้ @transaction เช่น คุณอาจเลือกความสอดคล้องที่อัปเดตภายหลังหากต้องการอัตราการส่งข้อมูล ความสามารถในการปรับขนาด หรือความพร้อมใช้งานที่สูงขึ้น อย่างไรก็ตาม คุณต้องจัดการฐานข้อมูลและโค้ดไคลเอ็นต์เพื่อให้รองรับผลลัพธ์ต่อไปนี้
- หากฟิลด์หนึ่งล้มเหลวเนื่องจากการดำเนินการฐานข้อมูล ฟิลด์ที่ตามมาจะดำเนินการต่อไป อย่างไรก็ตาม
@checkที่ล้มเหลวจะยังคงยุติการดำเนินการทั้งหมด - ระบบจะไม่ย้อนกลับ ซึ่งหมายความว่าฐานข้อมูลจะอยู่ในสถานะผสมที่มีการอัปเดตบางรายการสำเร็จและบางรายการล้มเหลว
- การดำเนินการที่มี
@checkอาจให้ผลลัพธ์ที่ไม่สอดคล้องกันมากขึ้นหากตรรกะ@checkใช้ผลลัพธ์ของการอ่านและ/หรือการเขียนในขั้นตอนก่อนหน้า - ผลลัพธ์ที่แสดงต่อโค้ดไคลเอ็นต์จะมีการผสมผสานที่ซับซ้อนมากขึ้นของการตอบกลับที่สำเร็จและล้มเหลว ซึ่งต้องจัดการ
คำสั่งสำหรับการเปลี่ยนแปลง SQL Connect
นอกเหนือจากคำสั่งที่คุณใช้ในการกำหนดประเภทและตารางแล้ว
SQL Connect ยังมี @auth, @check, @redact และ
@transaction เพื่อเพิ่มประสิทธิภาพการทำงานของการดำเนินการ
| คำสั่ง | นำไปใช้ได้กับ | คำอธิบาย |
|---|---|---|
@auth |
การค้นหาและการเปลี่ยนแปลง | กำหนดนโยบายการให้สิทธิ์เข้าถึงสำหรับการค้นหาหรือการเปลี่ยนแปลง ดู คู่มือการให้สิทธิ์เข้าถึงและการรับรอง |
@check |
ฟิลด์ query ในการดำเนินการหลายขั้นตอน |
ยืนยันว่าฟิลด์ที่ระบุมีอยู่ในผลการค้นหา ระบบจะใช้นิพจน์ Common Expression Language (CEL) เพื่อทดสอบค่าฟิลด์ ดู การดำเนินการหลายขั้นตอน |
@redact |
การค้นหา | ปกปิดส่วนหนึ่งของการตอบกลับจากไคลเอ็นต์ ดู การดำเนินการหลายขั้นตอน |
@transaction |
การเปลี่ยนแปลง | บังคับให้การเปลี่ยนแปลงทำงานในธุรกรรมฐานข้อมูลเสมอ ดู การดำเนินการหลายขั้นตอน |
ขั้นตอนถัดไป
หัวข้อที่คุณอาจสนใจ
- การสร้างการเปลี่ยนแปลงสำหรับแอปโดยใช้ เครื่องมือความช่วยเหลือจาก AI
- การให้สิทธิ์เข้าถึงการเปลี่ยนแปลงตามคู่มือการให้สิทธิ์เข้าถึง
- การเรียกการเปลี่ยนแปลงจากโค้ดไคลเอ็นต์สำหรับ เว็บ iOS, Android และ Flutter
- การดำเนินการข้อมูลจำนวนมากด้วยการเปลี่ยนแปลง