Menengah4 menit baca

Expression Attribute Name dan Value di DynamoDB

Expression DynamoDB adalah template: Anda menulis placeholder, lalu memasok nama atribut dan nilai nyata dalam dua peta samping. #name adalah placeholder nama; :value adalah placeholder nilai. Kelirukan keduanya dan DynamoDB menolak seluruh panggilan.

Apa beda antara #name dan :value di DynamoDB?

#name adalah placeholder untuk nama atribut, dipasok lewat ExpressionAttributeNames; :value adalah placeholder untuk nilai atribut, dipasok lewat ExpressionAttributeValues. Pakai #name untuk mengelak dari reserved word, titik, atau spasi, dan :value untuk setiap literal — DynamoDB tak pernah meng-inline nilai. Keduanya tak dapat dipertukarkan; menukarnya memunculkan ValidationException.

  • #name menggantikan nama atribut lewat ExpressionAttributeNames — gunakan ia setiap kali sebuah atribut bentrok dengan reserved word atau mengandung titik/spasi.
  • :value menggantikan nilai lewat ExpressionAttributeValues — DynamoDB tak pernah meng-inline literal ke dalam teks expression, jadi setiap nilai adalah placeholder.
  • Mereka tak dapat dipertukarkan. Sebuah # di tempat : seharusnya adalah ValidationException, bukan no-op senyap.

Datang dari SQL, Anda meng-inline keduanya — WHERE status = 'published'. DynamoDB tak meng-inline satu pun. Pemisahan itulah yang membingungkan setiap pendatang baru.

Mengapa kedua peta ada

Di SQL string query membawa segalanya: nama kolom, literal, operator. DynamoDB secara sengaja memisahkan bentuk expression dari data-nya.

Nilai masuk ke petanya sendiri agar DynamoDB bisa menentukan tipe masing-masing (S, N, BOOL, …) dan agar parser tak pernah harus menebak di mana sebuah string berakhir — tak ada quoting atau escaping untuk salah. Lihat tipe data di DynamoDB untuk daftar type-tag lengkapnya.

Nama mendapat perlakuan sama dengan alasan berbeda: DynamoDB punya daftar panjang reserved word, dan atribut mana pun yang cocok dengan satu tak bisa muncul sebagai nama telanjang dalam expression. Placeholder mengelak dari reservasi sepenuhnya.

Jebakan reserved-word

Ini sebuah tabel artikel CMS — partition key BLOG#<blog>, sort key ARTICLE#<slug> — yang atributnya terbaca alami tetapi kebetulan bentrok dengan reserved word:

AtributReserved?Apa yang ia tampung
statusyadraft / published
nameyanama tampilan penulis
sizeyapanjang byte ter-render
ttlyakedaluwarsa arsip (epoch)
slugtidakURL slug

status, name, size, dan ttl semuanya ada di daftar reserved-word AWS, jadi filter ini gagal pada kata pertama:

FilterExpression  status = :s

DynamoDB mengembalikan ValidationException"Attribute name is a reserved keyword; reserved keyword: status". Solusinya adalah placeholder nama, jangan pernah merename atributnya:

FilterExpression           #status = :s
ExpressionAttributeNames   { "#status": "status" }
ExpressionAttributeValues  { ":s": { "S": "published" } }

Jebakannya: slug tidak reserved, jadi query yang Anda uji terhadap slug bekerja, dan Anda berasumsi yang berikutnya juga begitu. Lalu status merusaknya. Daftar lengkapnya bergerak, jadi jangan menghafalnya — placeholder-kan setiap nama dan Anda tak pernah digigit.

Petakan setiap nilai, selalu

Nilai tak bisa ditawar: tak ada sintaks untuk literal inline. Bahkan angka biasa mendapat placeholder. Update ini menandai sebuah artikel published, mencap ukurannya, dan menyetel TTL arsip 30-hari:

UpdateExpression:          SET #status = :s, #size = :sz, #ttl = :exp
ExpressionAttributeNames:  { "#status": "status", "#size": "size", "#ttl": "ttl" }
ExpressionAttributeValues: {
  ":s":   { "S": "published" },
  ":sz":  { "N": "20480" },
  ":exp": { "N": "1719792000" }
}

Perhatikan :sz dan :exp dikirim sebagai string N — tipe number DynamoDB ter-encode di kabel sebagai string. Peta nilai juga tempat Anda menggunakan ulang sebuah nilai lintas klausa: definisikan :s sekali, referensikan ia di ConditionExpression dan FilterExpression.

Membangun kedua peta ini dengan tangan adalah tempat typo bersembunyi. Expression Builder menghasilkan string expression dan kedua peta bersama, dengan type tag terisi, jadi placeholder tak bisa melenceng dari sinkron.

Nama untuk path bersarang dan janggal

Placeholder # melakukan lebih dari sekadar mengelak reserved word. Sintaks document-path memakai titik dan kurung, jadi atribut yang secara harfiah mengandung titik — misalnya key metadata og.title — tak dapat dialamati tanpa placeholder:

ProjectionExpression       #og
ExpressionAttributeNames   { "#og": "og.title" }

Tanpa itu, DynamoDB membaca og.title sebagai "field title di dalam map og" — hal yang sama sekali berbeda. Cerita yang sama untuk nama dengan spasi atau angka di depan. Untuk bersarang, Anda placeholder-kan setiap segmen: #meta.#author dengan #meta dan #author keduanya terdefinisi.

Nama vs nilai, berdampingan

#name:value
Menggantikansebuah nama atributsebuah nilai atribut
PetaExpressionAttributeNamesExpressionAttributeValues
Prefiks#:
Dibutuhkan untukreserved word, titik, spasiselalu — tanpa literal inline
Yang salah errorValidationExceptionValidationException

Jika sebuah nilai diketik sebagai nama, DynamoDB akan mencari atribut bernama published dan kondisi Anda tak pernah cocok dengan cara yang Anda maksud — jadi API gagal keras alih-alih. Kekakuan itu adalah fitur: tak ada jawaban salah yang senyap.

Jebakan dan langkah berikutnya

  • Mendeklarasikan placeholder yang tak Anda pakai — DynamoDB menolak entri tak terpakai di salah satu peta. Bangun peta dari expression, bukan mendahuluinya.
  • Menggunakan ulang :v setelah mengedit expression — jatuhkan sebuah klausa dan nilainya bisa tertinggal, memicu error entri-tak-terpakai. Builder menjaganya selangkah.
  • Mengasumsikan nama aman karena pernah bekerja — bentrokan reserved-word bersifat per-atribut. Placeholder-kan secara seragam dan berhenti menebak.

Peta ini muncul di setiap jalur tulis, jadi mereka berpasangan alami dengan single-table design dan dengan mengetahui kapan harus Query vs Scan sebelum Anda pernah melampirkan sebuah filter.

Hasilkan expression plus kedua peta dengan Expression Builder, lalu coba DynoTable untuk menjalankannya terhadap tabel Anda sendiri dan menyaksikan placeholder teresolusi.

Diperbarui