Başlangıç11 dakikalık okuma

DynamoDB Tablosunu CSV'ye Aktarma (4 Yol)

DynamoDB'nin yerel bir "CSV'ye aktar" düğmesi yoktur. Her değer, DynamoDB'nin marshall edilmiş JSON'ına sarılı gelir — {"S": "..."}, {"N": "123"}, {"M": {...}} — ve bir tablo, bariz bir düz-sütun temsili olmayan iç içe haritalar, listeler ve kümeler tutabilir. Dolayısıyla "DynamoDB'yi CSV'ye aktarmak" aslında iki sorundur: öğeleri dışarı çıkarın, sonra türlenmiş JSON'ı satırlara düzleştirin. Ne konsol ne de yönetilen dışa aktarım ikinci adımı sizin için yapar.

Bu kılavuz, iki adımı da sizin için yapan yolla başlar, sonra üç AWS-araç rotasını ve her birinin ne zaman doğru çağrı olduğunu kapsar.

Bir DynamoDB tablosunu CSV'ye nasıl aktarırım?

En hızlı yol: tabloyu DynoTable'da açın, istediğiniz satırlara filtreleyin ve sonucu tek tıkla CSV'ye aktarın — tür tanımlayıcıları açılmış ve iç içe değerler sizin için düzleştirilmiş (Yöntem 1). Bunun yerine AWS araçlarıyla kurmak: küçük bir tablo için CLI ile tarayıp jq ile yeniden şekillendirin (Yöntem 2), büyük tablolar için yönetilen S3 dışa aktarımını kullanın (Yöntem 3) veya özel şekillendirme gerektiğinde kısa bir betik yazın (Yöntem 4).

  • Filtrelenmiş / şekillendirilmiş CSV (sütunların bir alt kümesi, yalnızca bazı öğeler): bir GUI dışa aktarımı (Yöntem 1) veya bir betik. Yönetilen S3 dışa aktarımı size tüm tabloyu, filtresiz verir.
  • Küçük tablo, geçici, yalnızca terminal: AWS CLI scan + jq (Yöntem 2). İç içe öznitelikler belirene kadar sorun yok.
  • Büyük tablo (GB'lar+): DynamoDB'nin S3'e dışa aktarımı (Yöntem 3), sonra dökümü dönüştürün. Eşzamansız çalışır ve okuma kapasitesi tüketmez — ama CSV değil, DynamoDB JSON çıktılar.

Yöntem 1: DynoTable'da tek tıkla dışa aktarma

DynoTable, dışa aktarmayı göz atmanın bir parçası olarak ele alır: bir sorgu çalıştırın veya filtreleyin, ⌘⇧E'ye basın (veya sekme araç çubuğundaki Export düğmesine) ve neyin çıkacağını seçin:

  • Biçimler: CSV (öğe başına bir satır, başlıklarla — kümeler bir hücrenin içinde JSON dizileri olarak serileştirilir), JSON ve NDJSON. JSON/NDJSON, unmarshall edilmiş (düz "count": 3) olarak veya büyük sayıları koruyan kayıpsız bir gidiş-dönüşe ihtiyacınız olduğunda marshall edilmiş DynamoDB-JSON olarak gelir.
  • Kapsamlar: şu anda yüklü satırlar, yalnızca seçiminiz veya tam filtre eşleşmesi — sorgunuzun eşleştiği her öğe, yalnızca ekranda olan değil, doğrudan DynamoDB'den akıtılarak. Bu sonuncusu, yönetilen S3 anlık görüntüsünün yapamadığı filtrelenmiş dışa aktarımdır.
  • Hedef: pano veya dosya. Tek seferlik kapmalar için bir satıra sağ tıklayın; Copy as…, CSV, JSON, NDJSON veya DynamoDB-JSON'ı iletişim kutusu olmadan doğrudan panoya koyar.
DynoTable'ın dışa aktarma iletişim kutusu: biçim (CSV / JSON / NDJSON), seçimden tam filtre eşleşmesine kapsam ve pano veya dosya hedefi.
DynoTable'ın dışa aktarma iletişim kutusu: biçim (CSV / JSON / NDJSON), seçimden tam filtre eşleşmesine kapsam ve pano veya dosya hedefi.

Aşağıdaki kendin-yap rotalarını kıran düzleştirme sorunları halledilmiştir: tür tanımlayıcıları açılır, iç içe haritalar ve listeler düzleştirilir ve yeniden adlandırılan sütunlar CSV başlıklarına akar. Büyük dışa aktarımlar ayrılır ve arka planda çalışır — satır satır diske akıtılır, sekme geçişlerinden ve hatta bir uygulama yeniden yüklemesinden sağ çıkar — böylece çok gigabaytlık bir dışa aktarımın asla belleğe sığması gerekmez.

Bu bir masaüstü DynamoDB istemcisidir, tabloya göz atmak için zaten kullandığınız araçtır; diğer DynamoDB GUI'leriyle nasıl karşılaştırıldığına bakın. Ne zaman kullan_maz_dınız? Dışa aktarımın bir boru hattında gözetimsiz çalışması gerektiğinde — betik rotası (Yöntem 4) bunun içindir.

Yöntem 2: AWS CLI scan + jq

Küçük bir tablo için onu tarayabilir ve çıktıyı jq ile yeniden şekillendirebilirsiniz. Bir Scan, tablodaki her öğeyi okur ve 1 MB'ye kadar sayfalar halinde döndürür; CLI sayfalamayı sizin için otomatik izler (AWS belgeleri: Tabloları tarama).

aws dynamodb scan --table-name MyTable --output json \
  | jq -r '.Items[] | [.id.S, .name.S, .price.N] | @csv' \
  > out.csv

Püf noktası o jq satırındadır: ham değere ulaşmak için her özniteliğin tür tanımlayıcısının (S, N, B, BOOL, M, L, SS, NS, BS) ötesine uzanarak .id.S, .name.S, .price.N'yi elle yazmak zorundasınız. Üç dize sütunlu düz bir tablo için idare edilebilir. Şunlara sahip olduğunuz anda dağılır:

  • İç içe haritalar/listeler{"M": {...}} veya {"L": [...]}'nin düzleşeceği tek bir sütun yoktur; @csv boğulur ya da hücreyi elle JSON-kodlarsınız.
  • Kümeler{"SS": ["a","b"]} bir skaler değil, bir dizidir.
  • Seyrek öznitelikler — DynamoDB şemasızdır, yani A öğesinde price olabilir, B öğesinde olmayabilir. Sabit sütun listeniz sütunları sessizce düşürür veya kaydırır.

Ayrıca hiç --output csv yoktur — CLI'ın çıktı biçimleri json, yaml, text, table ve off'tur; hiçbiri DynamoDB türlerini anlamaz. Yani tür etiketlerini soymak için yine jq (veya bir betik) gerekir. "AWS CLI ile DynamoDB tablosunu CSV'ye aktar"ın önemsiz durumun ötesinde asla tek satır olmamasının temel nedeni budur.

Daha büyük bir tablonun tamamını bu yolla bütün gün sürmeden dışa aktarmak için, taramayı --segment / --total-segments ile paralelleştirin (AWS belgeleri: Paralel tarama — DynamoDB "her öğenin bölüm anahtarına bir hash fonksiyonu uygulayarak öğeleri segmentlere atar", dolayısıyla segmentler dengesiz olabilir) ve ilk 1 MB sayfada durmamak için sayfalamayı okuyun.

Yöntem 3: DynamoDB'nin S3'e dışa aktarımı (büyük tablolar)

Gerçek boyuttaki tablolar için, yönetilen Amazon S3'e dışa aktarım doğru araçtır. Bir anlık görüntüyü point-in-time recovery (PITR) pencerenizdeki herhangi bir noktadan dışa aktarır — yani önce tabloda PITR etkin olmalıdır, yoksa dışa aktarım PointInTimeRecoveryUnavailableException ile başarısız olur — eşzamansız çalışır ve okuma kapasitesi birimi tüketmez, dolayısıyla tablonuzun throughput'u veya kullanılabilirliği üzerinde sıfır etkisi vardır (AWS belgeleri: "Dışa aktarımlar eşzamansızdır, okuma kapasitesi birimi (RCU) tüketmezler ve tablo performansı ile kullanılabilirliği üzerinde etkileri yoktur"; "Dışa aktarma işlevini kullanmak için tablonuzda PITR'yi etkinleştirmeniz gerekir"). Konsolun Exports to S3 eyleminin perde arkasında tetiklediği de budur: konsol aynı API için yalnızca bir ön yüzdür, dolayısıyla aynı PITR gereksinimini ve aynı JSON çıktısını taşır.

aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:us-east-1:123456789012:table/MyTable \
  --s3-bucket my-export-bucket \
  --export-format DYNAMODB_JSON

Tek tuzak: S3 dışa aktarımı CSV çıktılamaz. Yalnızca DynamoDB JSON veya Amazon Ion yazar — JSON-lines biçiminde (satır başına bir öğe) gzip'lenmiş dosyalar olarak, artı manifest dosyaları (AWS belgeleri: dışa aktarım çıktı biçimi — veri dosyaları .json.gz olarak yazılır, "biçim JSON lines'tır", manifest-summary.json / manifest-files.json ile birlikte). Sonrasında yine bir dönüştürme adımına ihtiyacınız var:

  • Athena / Glue, dışa aktarılan DynamoDB JSON'ı doğrudan okur — S3 önekine bir tablo doğrultun, sonra bir SELECT'ten CSV yazın (bu, olağan "DynamoDB'yi S3'e sonra CSV'ye aktar" boru hattıdır). AWS, "Athena ve AWS Glue gibi birçok AWS hizmeti bu biçimi otomatik olarak ayrıştırır" diye not eder (dışa aktarım çıktı biçimi).
  • Kendiniz yapın.gz dosyalarını açın, her JSON satırını ayrıştırın ve düzleştirin (diğer her yöntemle aynı düzleştirme sorunu).

Ayrıca bu bir tam tablo anlık görüntüsüdür: yalnızca bazı öğeleri dışa aktaracak sunucu tarafı bir filtre yoktur. Bir alt kümeye ihtiyacınız varsa, ya sonradan Athena'da filtrelersiniz ya da bir GUI (Yöntem 1) / betik kullanırsınız.

Yöntem 4: hızlı bir betik (boto3 / Node)

Dışa aktarım gözetimsiz çalışmak zorunda olduğunda — gecelik bir iş, bir CI adımı — küçük bir betik yukarıdaki her şeyi yener. Kazanç, AWS SDK'larının türlenmiş JSON'ı sizin için unmarshall etmesidir: boto3'ün resource arayüzü ve JS SDK'nın DynamoDBDocumentClient'ı, {"price": {"N": "2000"}} yerine düz {"price": 2000} döndürür (boto3'ün resource arayüzü "veri türlemesini örtük" yapar, AWS Python kılavuzuna göre; JS DocumentClient "açıklamalı yanıt verisini yerel JavaScript türlerine dönüştürür", @aws-sdk/lib-dynamodb'ye göre).

import boto3, csv

table = boto3.resource("dynamodb").Table("MyTable")
rows, resp = [], table.scan()
rows += resp["Items"]
while "LastEvaluatedKey" in resp:                  # paginate to the end
    resp = table.scan(ExclusiveStartKey=resp["LastEvaluatedKey"])
    rows += resp["Items"]

with open("out.csv", "w", newline="") as f:
    w = csv.DictWriter(f, fieldnames=["id", "name", "price"])
    w.writeheader()
    for r in rows:
        w.writerow({k: r.get(k) for k in w.fieldnames})

SDK'nın sizin yerinize veremeyeceği iki karar hâlâ size aittir: iç içe haritaları/listeleri sütunlara nasıl düzleştireceğiniz (hücreyi JSON-kodlamak mı? anahtarları nokta-yollamak mı?) ve seyrek özniteliklerle ne yapacağınız (burada eksik bir anahtar, r.get(k) ile boş bir hücre olur). Ve LastEvaluatedKey döngüsünü düşürmeyin — tek bir scan() çağrısı yalnızca ilk 1 MB sayfayı döndürür, onsuz tablonun bir kısmını sessizce dışa aktarırsınız.

Yöntem 2 ile aynı uyarı: buradaki tam tablo scan'i de okuma kapasitesi tüketir ve canlı trafikle rekabet eder. Büyük bir tablo için Yöntem 3'ü tercih edin ve dökümü yeniden şekillendirin.

Tuzaklar: DynamoDB JSON'a karşı düz CSV

Hangi yöntemi seçerseniz seçin, DynamoDB'nin veri modeli ile düz bir CSV arasındaki aynı bir avuç uyumsuzluk sizi ısıracaktır:

  • Tür tanımlayıcıları. Ham API / CLI / S3-dışa aktarım çıktısı her değeri sarar ({"S": "..."}, {"N": "123"}). Ya bir SDK ile açarsınız ya da tanımlayıcıyı kendiniz soyarsınız. Tam küme S, N, B, BOOL, NULL, M, L, SS, NS, BS'dir — bkz. DynamoDB veri türleri.
  • İç içe haritalar ve listeler (M, L) 32 seviye derinliğe kadar iç içe geçebilir (AWS belgeleri: veri türleri — liste ve harita "karmaşık veri yapılarını temsil etmek için birbirinin içine, 32 seviye derinliğe kadar iç içe geçebilir") ve doğal bir tek-sütun biçimleri yoktur. Baştan karar verin: hücreyi JSON-kodlayın veya iç içe anahtarları nokta-yollu sütunlara patlatın (address.city).
  • Kümeler (SS/NS/BS) skaler değil, sırasız koleksiyonlardır — AWS "bir küme içindeki değerlerin sırası korunmaz" diye uyarır (veri türleri) — dolayısıyla sınırlayıcılı bir dizeye düzleştirin ve eleman sırasına güvenmeyin.
  • Seyrek öznitelikler. DynamoDB şemasızdır, dolayısıyla iki öğe farklı özniteliklere sahip olabilir. Sabit bir sütun kümesi yoktur; anahtarların birleşimini tüm öğeler genelinde alın, yoksa sütunlar kayar. Bu, tek bir tablonun birkaç varlık şekli tuttuğu tek tablo tasarımının doğrudan bir sonucudur.
  • Sayfalama. Scan (ve Query) çağrı başına en fazla 1 MB döndürür. LastEvaluatedKey üzerinde döngü kurmazsanız, sessizce yalnızca ilk sayfayı dışa aktarırsınız. Bkz. sayfalama.
  • Sayı hassasiyeti. DynamoDB sayıları 38 basamağa kadar hassasiyet taşır ve dize olarak yolculuk eder (AWS belgeleri: veri türleri: "Sayılar 38 basamağa kadar hassasiyete sahip olabilir"; "Tüm sayılar DynamoDB'ye ağ üzerinden dize olarak gönderilir"); elektronik tablo yazılımı uzun sayıları veya kimlikleri float'lara zorlayıp basamak kaybedebilir. Onları metin olarak tutun.

SSS

Bir DynamoDB tablosunu CSV'ye aktarmanın en hızlı yolu nedir? Düzleştirmeyi sizin için yapan bir GUI: DynoTable'da tabloyu filtreleyin, ⌘⇧E'ye basın, CSV'yi seçin ve bir kapsam belirleyin — seçili satırlardan filtrenin eşleştiği her öğeye kadar, DynamoDB'den akıtılarak. Tür tanımlayıcıları ve iç içe değerler otomatik halledilir.

AWS CLI ile bir DynamoDB tablosunu CSV'ye nasıl aktarırım? Tabloyu tarayın ve çıktıyı jq ile yeniden şekillendirin (Yöntem 2): aws dynamodb scan → her değerin tür tanımlayıcısını soymak için jq@csv. DynamoDB-farkında bir --output csv yoktur, dolayısıyla tür soymayı her zaman kendiniz yaparsınız ve iç içe haritalarda, listelerde ve kümelerde kırılır.

AWS'den bir DynamoDB tablosunu doğrudan CSV'ye aktarabilir miyim? Tek adımda değil. Konsol ve yönetilen S3 dışa aktarımı, ikisi de DynamoDB JSON veya Amazon Ion üretir, asla CSV değil. Her zaman bir dönüştürme adımına ihtiyacınız var — CLI + jq, bir betik, S3 dökümü üzerinde Athena/Glue veya düzleştirmeyi sizin için yapan bir GUI.

Üretimi etkilemeden tüm bir DynamoDB tablosunu nasıl dışa aktarırım? S3'e dışa aktarma özelliğini kullanın (Yöntem 3). Eşzamansız çalışır ve okuma kapasitesi birimi tüketmez, dolayısıyla canlı trafikle rekabet etmez — tablonuzun throughput'una karşı ölçülen bir Scan'in aksine (AWS belgeleri). PITR'nin etkin olmasını gerektirir ve filtrelenmiş bir alt kümeyi değil, tam tabloyu dışa aktarır.

DynamoDB'yi S3'e CSV olarak nasıl aktarırım? Yönetilen dışa aktarım S3'e yalnızca DynamoDB JSON / Ion yazar, dolayısıyla "CSV'ye" ikinci bir sıçramadır: dışa aktarım önekini bir Athena (veya Glue) tablosu olarak kaydedin ve bir SELECT'ten CSV yazın. --export-format CSV yoktur.

DynamoDB'yi Excel'e nasıl aktarırım? Önce CSV'ye aktarın (yukarıdaki herhangi bir yöntem), sonra CSV'yi Excel'de açın — uzun sayısal kimlikleri float'lara zorlanmasınlar diye metin olarak tutarak. DynamoDB'den doğrudan .xlsx dışa aktarımı yoktur; DynoTable, geçerli görünümü doğrudan elektronik tabloya hazır bir CSV'ye kaydeder.

Dışa aktardığım JSON'da neden her yerde {"S": ...} ve {"N": ...} var? Bu, DynamoDB'nin tel biçimidir — her değer bir tür tanımlayıcısıyla etiketlenir. CSV yazmadan önce bir SDK, DynamoDB JSON dönüştürücüsü veya bir GUI ile unmarshall edin. Tel biçimi, veri API'den, CLI'dan veya S3 dışa aktarımından gelsin, aynıdır.

Kendi tablolarınıza göz atın, filtreleyin ve DynoTable ile CSV'ye aktarın — ya da önce bir DynamoDB JSON örneğini JSON dönüştürücüsünde açın.

Güncellendi