Şu ana kadar Kullanıcılar ve Fotoğraflar gibi mobil uygulamamızdaki çekirdek oluşumların sağlanması ve saklanması adına erişim modellerini başarıyla uyguladık. Varlıklarımızda ek sorgulama modellerini aktifleştirmek için dönüştürülmüş bir dizinin nasıl kullanılacağını da öğrendik.

Bu modülde iki erişim modelini uygulayacağız:

  • Bir fotoğrafa tepki verme (Yazma)
  • Arkadaş takip etme (Yazma)

Bu iki erişim modelinin her birinin şu ana kadar uyguladığımız okuma ağırlıklı modellere nazaran DynamoDB’ye veri yazdığını unutmayın

Aşağıdaki adımlarda yer alan her iki erişim modelini de uygulamak için DynamoDB ACID işlemlerini kullanacağız. DynamoDB işlemleri Kasım 2018’de duyuruldu. DynamoDB’de işlemlerin nasıl gerçekleştiğine dair hızlıca giriş düzeyinde bilgi edinelim.

Veri unsurlarını kısa sürede etkileyen ilişkisel faaliyetlerde bu işlemler çok yaygındır. Örneğin, bir banka işlettiğinizi düşünün. Karen adında bir müşteri, Sujith adındaki başka bir müşteriye 100 USD gönderiyor. Bu işlemin kaydı sırasında değişikliklerin her iki müşteri hesabına yansıdığından emin olmak için işlem özelliği kullanırsınız.

DynamoDB’ye işlemlerin eklenmesiyle tek bir faaliyetin bir parçası olarak birden fazla ögeyi değiştirmeniz gereken uygulamaların oluşturulması sürecini kolaylaştırmaktadır. DynamoDB işlemleriyle birlikte tek bir işlem isteminde en fazla 10 adet öge yürütebilirsiniz.

Bir TransactWriteItem (İşlem Yazdırma Ögesi) API çağrısı kapsamında şu faaliyet türlerini kullanabilirsiniz:

  • Yerleştir: Bir ögenin yerleştirilmesi veya ögenin üzerine yazım için.
  • Güncelle: Mevcut bir ögenin güncellenmesi için.
  • Sil: Bir ögenin silinmesi için.
  • Koşul Kontrolü: Ögeyi değiştirmeden ögeye bir koşul eklemek için.

Aşağıdaki adımlarda karmaşık faaliyetlerin üstesinden gelmek için iki şekilde DynamoDB işlemleri kullanacağız.

Modülü Tamamlama Süresi: 20 Dakika


  • 1. adım: Bir fotoğrafa tepki ver

    Bu modülde değineceğimiz ilk erişim modeli, bir fotoğrafa tepki verilmesidir.

    Bir fotoğrafa bir kullanıcının tepkisini eklerken birkaç şey yapmamız gerekmektedir:

    • Kullanıcının bu tür bir tepkiyi bu fotoğrafa hâlihazırda eklemiş olmadığını doğrulamak
    • Tepkiyi kaydetmek için yeni bir Tepki oluşturmak
    • Bir fotoğrafta tepki detaylarını görüntüleyebilmemiz için Fotoğraf varlığındaki tepkiler kapsamında uygun tepki türünü artırmak

    Bu işlemin iki farklı ögede yazdırma işlemi gerektirdiğini unutmayın -- nesnelerden biri için koşullu mantığa ek olarak mevcut Fotoğraf varlığı ve yeni Tepki varlığı -- . DynamoDB işlemleri için en uygun işlem türü budur.

    İndirdiğiniz kodda bir fotoğrafa bir tepki ekleme işlevi olan, add_reaction.py adındaki uygulama/ dizini kapsamında bir betik yer almaktadır. Bu dosyada yer alan işlev, bir tepki eklemek için DynamoDB işlemi kullanmaktadır.

    Dosyanın içerikleri aşağıdaki gibidir.

    import datetime
    
    import boto3
    
    dynamodb = boto3.client('dynamodb')
    
    REACTING_USER = 'kennedyheather'
    REACTION_TYPE = 'sunglasses'
    PHOTO_USER = 'ppierce'
    PHOTO_TIMESTAMP = '2019-04-14T08:09:34'
    
    
    def add_reaction_to_photo(reacting_user, reaction_type, photo_user, photo_timestamp):
        reaction = "REACTION#{}#{}".format(reacting_user, reaction_type)
        photo = "PHOTO#{}#{}".format(photo_user, photo_timestamp)
        user = "USER#{}".format(photo_user)
        try:
            resp = dynamodb.transact_write_items(
                TransactItems=[
                    {
                        "Put": {
                            "TableName": "quick-photos",
                            "Item": {
                                "PK": {"S": reaction},
                                "SK": {"S": photo},
                                "reactingUser": {"S": reacting_user},
                                "reactionType": {"S": reaction_type},
                                "photo": {"S": photo},
                                "timestamp": {"S": datetime.datetime.now().isoformat() }
                            },
                            "ConditionExpression": "attribute_not_exists(SK)",
                            "ReturnValuesOnConditionCheckFailure": "ALL_OLD"
                        },
                    },
                    {
                        "Update": {
                            "TableName": "quick-photos",
                            "Key": {"PK": {"S": user}, "SK": {"S": photo}},
                            "UpdateExpression": "SET reactions.#t = reactions.#t + :i",
                            "ExpressionAttributeNames": {
                                "#t": reaction_type
                            },
                            "ExpressionAttributeValues": {
                                ":i": { "N": "1" },
                            },
                            "ReturnValuesOnConditionCheckFailure": "ALL_OLD"
                        }
                    }
                ]
            )
            print("Added {} reaction from {}".format(reaction_type, reacting_user))
            return True
        except Exception as e:
            print("Could not add reaction to photo")
    
    add_reaction_to_photo(REACTING_USER, REACTION_TYPE, PHOTO_USER, PHOTO_TIMESTAMP)
    

    add_reaction_to_photo (fotoğrafa tepki ekle) işlevi kapsamında bir yazdırma işlemi için transact_write_items (işlem yazdırma ögeleri) yöntemini kullanıyoruz. İşlemimizde iki faaliyet yer almaktadır.

    İlk olarak, yeni bir Tepki varlığı eklemek için Yerleştir işlemi uyguluyoruz. Bu faaliyet kapsamında SK özniteliğinin bu varlık için gerçekleşmemesinin gerektiği bir koşul belirleriz. Böylelikle, PK ve SK unsurlarına sahip olan bir varlık da hâlihazırda var olmaz. Böyle bir varlık var olsaydı kullanıcının bu fotoğrafa hâlihazırda bir tepki eklediği anlaşılırdı.

    İkinci faaliyet tepkiler özniteliği haritasında tepki türünün arttırılması için Kullanıcı unsurunun üzerinde bir Güncelleme faaliyetidir. DynamoDB’nin güçlü güncelleme ifadeleri ögeyi elde edip güncelleme ihtiyacı olmadan atomik artışlar yapmanıza olanak tanımaktadır.

    Bu betiği aşağıdaki komut ile terminalinizde çalıştırın:

    python application/add_reaction.py

    Terminalinizdeki çıktı, fotoğrafa tepki eklendiğini göstermelidir.

    Added sunglasses reaction from kennedyheather

    Betiği tekrar çalıştırmayı denemeniz durumunda işlevin başarısız olacağını unutmayın. kennedyheather adlı kullanıcı bu fotoğrafa hâlihazırda bu tepkiyi eklemiştir. O nedenle, tekrar böyle bir şeye kalkışmak Tepki varlığının oluşturulmasına yönelik faaliyet kapsamındaki koşul ifadesini ihlal edecektir. Diğer bir deyişle, söz konusu işlev eş güçlü bir işlev olup aynı çıktıyı veren işlevin tekrarlanarak kullanımı istenmeyen sonuçları vermeyecektir.

    DynamoDB işlemlerinin eklenmesi bu gibi karmaşık faaliyetler kapsamında iş akışını sadeleştirmektedir. Daha önce, sorun oluşması hâlinde karmaşık koşulları ve manuel geri çağırma süreçlerini içeren birden fazla API çağrısı gerekirdi. Artık, 50 satırdan daha az kodla uygulamak mümkündür.

    Bir sonraki aşamada “Kullanıcıyı takip et” adlı erişim modelimizin nasıl kullanılacağını göreceğiz.

  • 2. Adım: Bir kullanıcının takip edilmesi

    Uygulamanızda bir kullanıcı diğerini takip edebilmektedir. Uygulamanın arka ucu bir kullanıcı takip isteği aldığında şu dört işlemi yapmamız gerekir:

    • Kullanıcının istek gönderilen kullanıcıyı hâlihazırda takip etmediğinden emin olmak;
    • Bu kapsamdaki ilişkinin kaydı için bir Arkadaşlık varlığı oluşturmak;
    • Takip edilen kullanıcı için takipçi sayısını artırmak;
    • Takip eden kullanıcı için takip edilen sayısını artırmak.

    İndirdiğiniz kodun, application/ dizininde follow_user.py isimli bir dosya vardır. Dosyanın içerikleri aşağıdaki gibidir.

    import datetime
    
    import boto3
    
    dynamodb = boto3.client('dynamodb')
    
    FOLLOWED_USER = 'tmartinez'
    FOLLOWING_USER = 'john42'
    
    
    def follow_user(followed_user, following_user):
        user = "USER#{}".format(followed_user)
        friend = "#FRIEND#{}".format(following_user)
        user_metadata = "#METADATA#{}".format(followed_user)
        friend_user = "USER#{}".format(following_user)
        friend_metadata = "#METADATA#{}".format(following_user)
        try:
            resp = dynamodb.transact_write_items(
                TransactItems=[
                    {
                        "Put": {
                            "TableName": "quick-photos",
                            "Item": {
                                "PK": {"S": user},
                                "SK": {"S": friend},
                                "followedUser": {"S": followed_user},
                                "followingUser": {"S": following_user},
                                "timestamp": {"S": datetime.datetime.now().isoformat()},
                            },
                            "ConditionExpression": "attribute_not_exists(SK)",
                            "ReturnValuesOnConditionCheckFailure": "ALL_OLD",
                        }
                    },
                    {
                        "Update": {
                            "TableName": "quick-photos",
                            "Key": {"PK": {"S": user}, "SK": {"S": user_metadata}},
                            "UpdateExpression": "SET followers = followers + :i",
                            "ExpressionAttributeValues": {":i": {"N": "1"}},
                            "ReturnValuesOnConditionCheckFailure": "ALL_OLD",
                        }
                    },
                    {
                        "Update": {
                            "TableName": "quick-photos",
                            "Key": {"PK": {"S": friend_user}, "SK": {"S": friend_metadata}},
                            "UpdateExpression": "SET following = following + :i",
                            "ExpressionAttributeValues": {":i": {"N": "1"}},
                            "ReturnValuesOnConditionCheckFailure": "ALL_OLD",
                        }
                    },
                ]
            )
            print("User {} is now following user {}".format(following_user, followed_user))
            return True
        except Exception as e:
            print(e)
            print("Could not add follow relationship")
    
    follow_user(FOLLOWED_USER, FOLLOWING_USER)

    Dosya içerisindeki follow_user işlevi uygulamanızda yer alan işleve benzerdir. Bu minvalde iki kullanıcı adı gerekmektedir -- takip edilen ve takip eden kullanıcılardan biri -- bir Arkadaşlık varlığı oluşturmak ve iki Kullanıcı varlığını güncellemek için bir istek gerekmektedir.

    Betiği aşağıdaki komutla terminalinizde çalıştırın:

    python application/follow_user.py

    Terminalinizde çıktıyı görmelisiniz. Bu çıktı işlemin başarılı olduğunu göstermektedir.

    User john42 is now following user tmartinez

    Terminalinizde betiği tekrar yürütmeyi deneyin. Bu kez, takip ilişkisini ekleyemediğinizi gösteren bir hata mesajı almanız gerekmektedir. Bu durumun sebebi, bu kullanıcının istek gönderilen kullanıcıyı artık takip ediyor olmasıdır. Bu nedenle, ögeye yönelik koşullu kontrol talebimiz başarısız olmuştur.

  • Sonuç

    Bu modülde, uygulama içerisinde iki gelişmiş yazma faaliyetinin nasıl yürütüleceğini de gördük. İlk olarak, bir kullanıcının bir fotoğrafa tepki göstermesi için DynamoDB işlemleri kullandık. İşlemlerle birlikte tek bir istek kapsamında birden farklı öge içerisinde karmaşık koşullu yazma işlemlerini gerçekleştirdik. Ayrıca, bir harita varlığı içerisinde iç içe özniteliğin artırılması adına DynamoDB güncelleme tepkilerinin nasıl kullanılacağını gördük.

    Daha sonra, bir kullanıcının diğer kullanıcıyı takip etmesi için işlevi uyguladık. Bu süreç, ögelerden birinde koşullu kontrol gerçekleştirirken tek bir istek kapsamında üç ögenin değiştirilmesi gerektirdi. Bu normalde zor bir işlem olsa da DynamoDB işlemleriyle sürecin idaresi daha kolay bir hâl almaktadır.

    Bir sonraki modülde oluşturduğumuz kaynakları temizleyeceğiz ve DynamoDB öğrenme yolumuzdaki sonraki adımlardan bazılarını göreceğiz.