如何更新GoogleAppEngine for Python中的StringListProperty?

时间:2016-01-24 08:49:19

标签: google-app-engine google-app-engine-python

我目前有一个Events(db.Model)类,如下所示:

from bottle import route, run, request
import spotipy
from spotipy import oauth2

PORT_NUMBER = 8080
SPOTIPY_CLIENT_ID = 'your_client_id'
SPOTIPY_CLIENT_SECRET = 'your_client_secret'
SPOTIPY_REDIRECT_URI = 'http://localhost:8080'
SCOPE = 'user-library-read'
CACHE = '.spotipyoauthcache'

sp_oauth = oauth2.SpotifyOAuth( SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET,SPOTIPY_REDIRECT_URI,scope=SCOPE,cache_path=CACHE )

@route('/')
def index():

    access_token = ""

    token_info = sp_oauth.get_cached_token()

    if token_info:
        print "Found cached token!"
        access_token = token_info['access_token']
    else:
        url = request.url
        code = sp_oauth.parse_response_code(url)
        if code:
            print "Found Spotify auth code in Request URL! Trying to get valid access token..."
            token_info = sp_oauth.get_access_token(code)
            access_token = token_info['access_token']

    if access_token:
        print "Access token available! Trying to get user information..."
        sp = spotipy.Spotify(access_token)
        results = sp.current_user()
        return results

    else:
        return htmlForLoginButton()

def htmlForLoginButton():
    auth_url = getSPOauthURI()
    htmlLoginButton = "<a href='" + auth_url + "'>Login to Spotify</a>"
    return htmlLoginButton

def getSPOauthURI():
    auth_url = sp_oauth.get_authorize_url()
    return auth_url

run(host='', port=8080)

我创建了一个HTML文件,该文件派生了一个将附加到此StringListProperty的事件名称。我希望为特定用户更新此StringListProperty,而不是编辑任何其他属性。我知道有一种从实体查询特定用户名的方法:

class User(db.Model):
    name = db.StringProperty(required = True)
    pw_hash = db.StringProperty(required = True)
    email = db.EmailProperty(required = True)
    position = db.StringProperty(required = True)
    signedevents = db.StringListProperty()

我可能会使用它来更新该特定用户的signedevents属性。但是,我认为这非常低效,而且很可能无效。更新现有用户的StringListProperty的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

使用数据存储区无法做到这一点。

您已获得该实体。更新该实体的特定StringList属性,并将整个实体写回数据存储区。

您认为效率低下的事实不会改变数据存储区的工作原理。

现在,如果此实体很大(许多属性和索引),上面包含的模型不是,并且您有大量更新,那么您可能会考虑将模型拆分为频繁更新和不经常更新的部分,或经常使用的vs不经常使用的属性。

答案 1 :(得分:0)

首先,我建议您为模型使用ndb代替db。在后台写入数据存储区时,它将使用memcache将实体保存在内存中。后续请求(按键)将更快。

其次,利用Property Options使您的数据存储区写入更有效:

class User(ndb.Model):
    name = ndb.StringProperty('n', required = True)
    pw_hash = ndb.StringProperty('h', required = True, indexed = False)
    email = ndb.EmailProperty('e', required = True, indexed = False)
    position = ndb.StringProperty('p', required = True, indexed = False)
    signedevents = ndb.StringListProperty('e', indexed = False)

使用第一个参数指定数据存储区中的属性名称,并添加indexed = False以避免在每次写入时更新额外的索引(当然,除非您需要将它们编入索引)。

第三,也许使用@ timhoffman的建议将频繁更新的值拆分为另一个实体。在UserSignedEvents之间创建一对一的关系,并独立更新StringListProperty。