我正在使用App Engine数据存储区,并且希望确保行ID与mySQL DB中的“自动增量”字段的行为类似。
尝试了几种策略,但似乎无法控制发生的事情:
这样的事情可能吗? 我真的想避免为每一行保留(索引)时间戳。
答案 0 :(得分:1)
我所知道的是,Google App Engine中可以使用自动生成的ID作为长整数,但不能保证该值正在增加,并且也无法保证这些数字是实际的一个增量。
因此,如果您需要时间戳和增量,请添加一个DateTime字段,但是您不知道这些数字是唯一的。
所以,最好的(我们正在使用的)是:(对不起,但这确实是恕我直言的最佳选择)
答案 1 :(得分:1)
听起来像can't rely on IDs being sequential没有相当多的额外工作。但是,有一种简单的方法可以实现您的目标:
我们想要删除旧项目(超过两个月的价值,因为 例如)
这是一个自动跟踪其创建和修改时间的模型。只需使用auto_now_add
和auto_now
参数就可以实现这一点。
from google.appengine.ext import db
class Document(db.Model):
user = db.UserProperty(required=True)
title = db.StringProperty(default="Untitled")
content = db.TextProperty(default=DEFAULT_DOC)
created = db.DateTimeProperty(auto_now_add=True)
modified = db.DateTimeProperty(auto_now=True)
然后,您可以使用cron jobs或task queue来安排删除旧内容的维护任务。找到最旧的东西就像按创建日期或修改日期排序一样简单:
db.Query(Document).order("modified")
# or
db.Query(Document).order("created")
答案 2 :(得分:0)
我认为这可能是一个相当不错的解决方案,但要注意我没有以任何方式,形状或形式测试。语法甚至可能不正确!
原则是使用memcache生成单调序列,如果memcache失败,则使用数据存储区提供回退。
class IndexEndPoint(db.Model):
index = db.IntegerProperty (indexed = False, default = 0)
def find_next_index (cls):
""" finds the next free index for an entity type """
name = 'seqindex-%s' % ( cls.kind() )
def _from_ds ():
"""A very naive way to find the next free key.
We just take the last known end point and loop untill its free.
"""
tmp_index = IndexEndPoint.get_or_insert (name).index
index = None
while index is None:
key = db.key.from_path (cls.kind(), tmp_index))
free = db.get(key) is None
if free:
index = tmp_index
tmp_index += 1
return index
index = None
while index is None:
index = memcache.incr (index_name)
if index is None: # Our index might have been evicted
index = _from_ds ()
if memcache.add (index_name, index): # if false someone beat us to it
index = None
# ToDo:
# Use a named task to update IndexEndPoint so if the memcache index gets evicted
# we don't have too many items to cycle over to find the end point again.
return index
def make_new (cls):
""" Makes a new entity with an incrementing ID """
result = None
while result is None:
index = find_next_index (cls)
def txn ():
"""Makes a new entity if index is free.
This should only fail if we had a memcache miss
(does not have to be on this instance).
"""
key = db.key.from_path (cls.kind(), index)
if db.get (key) is not None:
return
result = cls (key)
result.put()
return result
result = db.run_in_transaction (txn)