【问题标题】:Google app engine database values not incrementing谷歌应用引擎数据库值不递增
【发布时间】:2011-01-19 13:52:58
【问题描述】:

这里有一些代码无法正常工作。每次查询数据库时,我都会得到选项的 0 或 1 值,并且数据库中的值不会增加,即使如您所见,在第 86 行和第 89 行中,值正在增加。知道这里出了什么问题吗?我在 Google App 引擎上使用 Django。

        user_result = request.POST['json']
 65     user_result = json.loads(user_result)
 66     user_country = get_user_country(user_result)
 67     question_number = get_question_number(user_result)
 68     answered_option = get_answered_option(user_result)
 69 
 70     country_option_1 = 0
 71     country_option_2 = 0
 72     world_option_1 = 0
 73     world_option_2 = 0
 74 
 75     """
 76     Get already existing record for the question for the contry, or create
 77     new one and put/update in db
 78     """
 79 
 80     country_wide_data = db.GqlQuery("SELECT * FROM CountryWideData WHERE country = :1 AND questionNo = :2", user_country, question_number)
 81     flag = False
 82     for i in country_wide_data:
 83         flag = True
 84     if flag:
 85         if answered_option==1:
 86             country_wide_data[0].optionOne = country_wide_data[0].optionOne + 1
 87 
 88         elif answered_option==2:
 89             country_wide_data[0].optionTwo = country_wide_data[0].optionTwo + 1
 90         country_option_1 = country_wide_data[0].optionOne
 91         country_option_2 = country_wide_data[0].optionTwo
 92         country_wide_data[0].put()
 93     else:
 94         country_wide_data = CountryWideData(country=user_country, questionNo=question_number)
 95 
 96         if answered_option==1:
 97             country_wide_data.optionOne = 1
 98             country_wide_data.optionTwo = 0
 99         elif answered_option==2:
100             country_wide_data.optionOne = 0
101             country_wide_data.optionTwo = 1
102         country_option_1 = country_wide_data.optionOne
103         country_option_2 = country_wide_data.optionTwo
104         country_wide_data.put()

【问题讨论】:

    标签: database django google-app-engine gql


    【解决方案1】:

    您从未使用 fetch() 来实际执行您在第 80 行创建的 GqlQuery。

    试试这个:

    country_wide_data = db.GqlQuery("SELECT * FROM CountryWideData WHERE country = :1 AND questionNo = :2", user_country, question_number).fetch()
    

    顺便说一句,您将希望在事务内部执行此递增操作;否则,如果多个请求可以执行此代码,您将获得竞争条件,并且计数将不准确。交易文档在这里:http://code.google.com/appengine/docs/python/datastore/transactions.html

    一般来说,您会希望获取创建或更新这些实体的代码并将它们放入函数中,如下所示:

    def increment_existing_data(key, answered):
        cwd_to_incr = db.get(key)
        if answered == 1:
            cwd_to_incr.optionOne += 1
        elif answered == 2:
            cwd_to_incr.optionTwo += 1
        cwd_to_incr.put()
    
    def create_new_data(answered, user_country, question_number):
        new_data = CountryWideData(country=user_country, questionNo=question_number)
        if answered == 1:
            new_data.optionOne = 1
            new_data.optionTwo = 0
        elif answered == 2:
            new_data.optionOne = 0
            new_data.optionTwo = 1
        new_data.put()
    

    然后,您可以使用 db.run_in_transacation 方法调用这些函数,如下所示:

    country_wide_data = db.GqlQuery("SELECT * FROM CountryWideData WHERE country = :1 AND questionNo = :2", user_country, question_number).get()
    if country_wide_data is not None:
        db.run_in_transaction(increment_existing_data, country_wide_data.key(), answered_option)
    else:
        db.run_in_transaction(create_new_data, answered_option,  user_country, question_number)
    

    【讨论】:

    • 感谢亚当!虽然 fetch 需要一个参数。 fetch(1) 为我工作。
    • Adams,您将如何使用事务更新值的任何示例代码?似乎 GQL 不允许更新语句。 ://
    • Shuaib:要执行交易,请删除所有 put 语句,并在循环后立即添加:dp.put(country_wide_data)。
    • dannyroa,这是不正确的。只有一个 put() 语句将确保对实体的所有更改同时发生,但它不会做任何事情来阻止两个不同的用户同时增加实体,从而导致后进-赢得行为和无理数。 Shuaib,我添加了一些代码示例,以帮助您了解如何使用事务。
    • 在事务中更新计数器将解决竞争条件,但它不能很好地扩展。如果每秒有超过两个事务,您可能会看到必须捕获和处理的 TransactionFailedError。谷歌有一个很好的分片计数器教程来解决竞争条件问题和事务扩展问题:code.google.com/appengine/articles/sharding_counters.html
    猜你喜欢
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2013-05-17
    • 2014-07-05
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多