Orta6 dakikalık okuma

DynamoDB'den TypeScript Tipleri Üretme

Postgres'te information_schema'yı iç gözlemleyecek ve ondan türler oluşturacaksınız. DynamoDB'ün eşdeğeri yoktur: DynamoDB hiçbir öğe şemasını saklamaz. Yalnızca öznitelikler Servisin bildiği anahtarlarda kullanılanlar nelerdir? DescribeTable'ler AttributeDefinitions kendi kapsamı konusunda açıktır: her bir girdi "açıklamaktadır" tablodaki ve dizin anahtarı şemasındaki bir özellik" (AWS API referansı) — tablonuzun diğer elli özelliği hiçbir yere kaydedilmez.

Dolayısıyla "DynamoDB'dan TypeScript türleri oluştur" her zaman şu üç şeyden biri anlamına gelir: Şekli kendiniz beyan edin, onu yazdığınız bir şemadan türatın kodunu kullanın veya onu gerçekten var olan öğelerden çıkarın.

Bir DynamoDB tablosu için TypeScript tiplerini nasıl alırım?

Bir tablonun öğe şeklini döndüren API yoktur; yalnızca DescribeTable bilir temel nitelikler. Seçenekleriniz: interface'i elle yazın ve şu adreste doğrulayın: sınır (bir Zod şeması türleri ve çalışma zamanını kontrol eder yapıt), yazdığınız şemanın sağladığı şema öncelikli kitaplığı kullanın. komut dosyasıyla veya benzeri bir araçla gerçek öğelerden şekli çıkarın DynoTable tabloyu tarayıp bir TypeScript dışa aktarır arayüzü, Zod şeması veya JSON Şeması.

Yöntem 1: interface'i elle yaz + sınırda doğrula

AWS SDK öğelerinizi senin için yazamaz. v3 Document istemcisi geri dönüyor öğeler türlenmemiş kayıtlar olarak — her GetCommand / QueryCommand sonucu sen aksini iddia edene kadar etkili bir şekilde Record<string, unknown>. Çıplak as Order cast sorunsuz şekilde derlenir ve çalışma zamanında yalan söyler, bu nedenle sağlamdır version, arayüzü bir çalışma zamanı kontrolüyle eşleştirir:

import {z} from 'zod';

const Order = z.object({
  PK: z.string(), // ORDER#<id>
  SK: z.string(), // META
  status: z.enum(['open', 'shipped', 'cancelled']),
  total: z.number(),
  couponCode: z.string().optional() // sparse attribute
});
type Order = z.infer<typeof Order>;

const {Item} = await doc.send(new GetCommand({TableName: 'Orders', Key: key}));
const order = Order.parse(Item); // typed AND verified

Bir şema, iki iş: z.infer sana statik türü verir, parse statik türü yakalar onunla eşleşmeyen öğe - şemasız bir mağazada bu bir when'dir, bir değil if. İşin püf noktası da aynı derecede basit: şema senin niyetinizi belgeliyor, değil senin tablon. Hiçbir şey eski bir yazarın total'yi bir dosya olarak saklamasına engel olamaz. dize ve elle yazılan türler, veriler geliştikçe sessizce sürüklenir.

Ham (Belge istemcisi olmayan) API çıktıdan çalışıyorsanız kabloyu unutmayın şekil DynamoDB-JSON ({"S": "..."}, {"N": "123"}) tür etiketlidir - bkz. marshalling ve tuşunu kullanın. Bir örneği çevirmek için DynamoDB JSON converter Şemayı yazarken tel ve düz form arasında.

Method 2: schema-first libraries

ElectroDB ve DynamoDB-Toolbox gibi araç setleri sürüklenme sorununa çözüm buluyor yazma tarafından: kodda bir varlık şeması yazarsınız ve kütüphane TypeScript türlerini türetir and her okuma ve yazmada şekli uygular gerçekleştirir. Bu mevcut en güçlü garantidir - ancak şunu unutmayın: yön: şemayı yazarsınız; kütüphane onu keşfetmez. İşaret ederek Mevcut bir tabloda bir tane olmak hâlâ öğe şekillerine tersine mühendislik uygulamak anlamına geliyor önce kendiniz yapın ve kütüphanenin dışında yazılan öğeler kütüphanenin dışındadır. garanti eder. Yeşil alanda parlıyorlar single-table designs her varlığın ilk günden itibaren araç setinden geçtiği yer.

Yöntem 3: tipleri gerçek öğelerden çıkar

Mevcut bir tablo için temel gerçek verilerdir. Bir örneği tarayın, şekilleri birleştirin:

const seen = new Map<string, Set<string>>(); // attr -> observed types
let count = 0;
let key: Record<string, unknown> | undefined;
do {
  const page = await doc.send(new ScanCommand({TableName: 'Orders', ExclusiveStartKey: key}));
  for (const item of page.Items ?? []) {
    count++;
    for (const [attr, value] of Object.entries(item)) {
      const t = Array.isArray(value) ? 'array' : typeof value;
      (seen.get(attr) ?? seen.set(attr, new Set()).get(attr)!).add(t);
    }
  }
  key = page.LastEvaluatedKey;
} while (key && count < 5000);
// emit: attribute -> type union, optional if seen in < count items

Saf versiyonun hemen karşılaştığı gerçek dünyadaki tuzaklar:

  • Seyrek nitelikler. Bir tablodaki DynamoDB öğenin farklı özellikleri olabilir nitelikler; Maddelerin %80'inde bulunan bir özellik optional'dir, değil kayıp. Yalnızca varlık durumunu değil, özellik başına sıklığı da izleyin.
  • Karma kuruluşlar. single-table design'da, USER# ve ORDER# öğeleri tabloyu paylaşır; her ikisi için birleştirilmiş tek arayüz işe yaramaz. Numuneyi şuna göre bölümlendirin: type attribute ve her biri bir tür yayar varlık.
  • Çarpışmaları yazın. Burada N ve orada S olarak depolanan özniteliğin aynısı gerçek (ve yaygın) bir veri hatası — sessizce değil, bir bütün olarak ortaya çıkıyor birini seçiyorum. Tam etiket seti data types'dedir.
  • Örnek örnektir. Yalnızca nadir öğelerde görünen özellikler, ilk 5.000'iniz arasında olun — her iki durumda da tarama maliyeti okuma kapasitesine mal olur (query vs scan).

DynoTable'da tek tıkla çıkarım

Bu çıkarım komut dosyası - örnekleme, frekans izleme, iç içe geçmiş yollar, varlık başına bölünme — DynoTable'ün Tablo istatistikleri'nde yerleşiktir paneli:

  1. Bir tablo açın, sekme araç çubuğundaki Ayarlar düğmesine basın ve Indexleme bölümünde Dizin tablosuna tıklayın. DynoTable canlı ilerleme ve kayıtlarla tabloyu örnekler bulduğu nitelikler - noktalı yolla iç içe geçmiş olanlar da dahil olmak üzere commonData.status — her birinin türü ve gerekli mi yoksa taranan satırlar boyunca isteğe bağlı. Tarama sınırlıdır, dolayısıyla bir özellik yalnızca nadir görülen öğeler eksik olabilir; görmek Tablo genel bakışı ve dizinleme.
  2. Dışa Aktar'a tıklayın ve bir format seçin:
    • TypeScript — bir interface.
    • Zodz.object(...) şeması (Standart Şema uyumlu).
    • JSON Şema — taslak 2020-12.
  3. Panoya kopyalayın veya bir dosyaya kaydedin.
DynoTable'ın Indexleme bölümü: türleri ve gerekli/isteğe bağlı bayrakları içeren dizinlenmiş alan listesi ve şema Dışa Aktarma düğmesi.
DynoTable'ın Indexleme bölümü: türleri ve gerekli/isteğe bağlı bayrakları içeren dizinlenmiş alan listesi ve şema Dışa Aktarma düğmesi.

Dışa aktarmanın ne olduğu konusunda dürüsttür: oluşturulan her şema bir bunun örneklenen öğelerden çıkarıldığını unutmayın; güçlü bir başlangıç yetkili bir sözleşme değil. İsteğe bağlılık her birinin ne sıklıkta olduğunu yansıtır öznitelik indeksleme sırasında ortaya çıktı ve birincil anahtar öznitelikleri her zaman gerekli olarak işaretlendi. Dizine ekleme normal DynamoDB okuma maliyetlerine neden olur ve Yeniden Dizinleme verileriniz değiştikten sonra resmi yeniler.

SSS

DescribeTable'dan türler üretebilir miyim? Yalnızca anahtar öznitelikler için. AttributeDefinitions, tablo ve dizin anahtar şemasını kapsar — öğeleriniz hakkında başka hiçbir şey hizmet tarafından saklanmaz, dolayısıyla iç gözlemlenecek sunucu tarafı bir şema yoktur.

Mevcut bir üretim tablosunu türlemenin en iyi yolu nedir? Önce çıkarsayın, sonra sağlamlaştırın: gerçek şekli elde etmek için gerçek öğeleri örnekleyin (betik veya DynoTable'ın dizinlenmiş dışa aktarımı), gözden geçirin ve gelecekteki sapma sınırda yakalansın diye onu elinizde tuttuğunuz bir Zod şemasına veya şema-öncelikli bir kütüphane varlığına terfi ettirin.

Tek tabloda birden çok varlık türünü nasıl ele alırım? Varlık başına bir tür, asla tek bir birleştirilmiş tür değil. Örneklemi tür özniteliğinize (veya anahtar önekine) göre bölün ve her biri için ayrı bir arayüz üretin — bunların ayrımlı birleşimi, tablonuzun türüdür.

Üretilen türlerim zorunlu bir alanı neden isteğe bağlı diyor? Çünkü örneklenen bir öğede o alan yoktu. Şemasız bir depoda isteğe bağlılık bir bildirim değil, bir gözlemdir — o öğelerin geriye doldurulacak eski satırlar mı (bkz. geçişler) yoksa gerçekten isteğe bağlı bir öznitelik mi olduğunu kontrol edin.

Türler DynamoDB kümelerini ve ikili verileri kapsıyor mu? Bir dönüştürücü düz-JSON temsilleri seçmek zorundadır: kümeler dizilere, ikili veri kodlanmış bir dizeye dönüşür — marshalling bölümünde ele alınan aynı eşleme tuhaflıkları. Özniteliklerinizin her iki tarafta tam olarak neye benzediğini görmek için bir örneği DynamoDB JSON dönüştürücüsünden gidiş-dönüş geçirin.

Tablonuzun şeklini tahmin etmeyi bırakın — DynoTable'ı indirin, tabloyu dizinleyin ve tek tıkla bir TypeScript, Zod veya JSON Schema dışa aktarın.

Güncellendi