类型和 Property 类

注意强烈建议构建新应用的开发者使用 NDB 客户端库,它与 DB 客户端库相比具有多项优势,例如可通过 Memcache API 进行自动实体缓存。如果您当前使用的是较早的 DB 客户端库,请参阅 DB 到 NDB 的迁移指南

App Engine Datastore 支持为数据实体上的属性使用固定的一组值类型。 您也可通过 Property 类来定义新类型,新类型可与基础值类型进行相互转换,在 Expando 动态属性和 ListProperty 聚合属性模型中可直接使用值类型。

下表介绍了一些 Property 类,其值直接对应于基础数据类型。这些值类型中的任何一个都可在 Expando 动态属性或 ListProperty 聚合类型中使用。

Property 类 值类型 排序顺序
IntegerProperty int
long (64 位)
数字
FloatProperty float 数字
BooleanProperty bool False < True
StringProperty str
unicode
Unicode(将 str 作为 ASCII 处理)
TextProperty db.Text
ByteStringProperty ByteString
字节顺序
BlobProperty db.Blob
DateProperty
TimeProperty
DateTimeProperty
datetime.date
datetime.time
datetime.datetime
时间顺序
GeoPtProperty db.GeoPt 先按纬度排序,
再按经度排序
PostalAddressProperty db.PostalAddress Unicode
PhoneNumberProperty db.PhoneNumber Unicode
EmailProperty db.Email Unicode
UserProperty users.User 按 Unicode 顺序排序的
电子邮件地址。请注意,根据 UserProperty 类说明下的备注,您应避免使用 UserProperty
IMProperty db.IM Unicode
LinkProperty db.Link Unicode
CategoryProperty db.Category Unicode
RatingProperty db.Rating 数字
ReferenceProperty
SelfReferenceProperty
db.Key 按路径元素
(种类、标识符、
种类、标识符...)排序
blobstore.BlobReferenceProperty blobstore.BlobInfo 字节顺序
ListProperty
StringListProperty
受支持类型的 list 如果按升序排序,则从最小的元素开始排序;
如果按降序排序,则从最大的元素开始排序

Datastore 值类型

Datastore 实体属性值可以是以下类型之一。如需 Model 定义中使用的相应 Property 类的列表,请参阅上文。

除了 Python 标准类型和 users.User 之外,本节中描述的所有类均由 google.appengine.ext.db 模块提供。

strunicode

短字符串(1500 个字节或更短)。

假设 str 值是用 ascii 编解码器编码的文本,在存储之前会被转换为 unicode 值。数据存储区会以 unicode 值返回该值。对于使用其他编解码器的短字符串,请使用 unicode 值。

Datastore 会将短字符串编入索引,如此便可在过滤条件和排序顺序中使用短字符串。对于长度超过 1500 个字节的文本字符串(未编入索引),请使用 Text 实例。对于长度超过 1500 个字节的未编码字节字符串(也未编入索引),请使用 Blob 实例。对于应编入索引的长度不超过 1500 个字节(非字符数)的非文本未编码字节字符串,请使用 ByteString 实例。

模型属性:StringProperty

bool

布尔值(TrueFalse)。

模型属性:BooleanProperty

intlong

整数值,最多 64 位。

Python int 值会在存储之前转换为 Python long 值。因此以 int 存储的值将作为 long 返回。

如果分配了一个超过 64 位的 long,系统只会存储 64 位的最低有效位。

模型属性:IntegerProperty

float

浮点数。

模型属性:FloatProperty

datetime.datetime

日期和时间。请参阅 datetime 模块文档

如果 datetime 值具有 tzinfo 特性 (attribute),则它在存储时将转换为世界协调时间 (UTC) 时区。因此从数据存储区返回的将是 tzinfoNone 的 UTC 值。对于需要特定时区的日期和时间值的应用,必须在更新值时正确设置 tzinfo,并在访问该值时将其转换为相应时区。

某些库会使用 TZ 环境变量控制日期时间值适用的时区。App Engine 将此环境变量设置为 "UTC"。请注意,在应用中更改此变量将不会更改某些日期时间函数的行为,这是因为在 Python 代码之外对环境变量进行的更改不可见。

如果您只是在某个特定时区来回转换值,则可以执行自定义 datetime.tzinfo 来转换数据存储区中的值:

import datetime
import time

class Pacific_tzinfo(datetime.tzinfo):
    """Implementation of the Pacific timezone."""
    def utcoffset(self, dt):
        return datetime.timedelta(hours=-8) + self.dst(dt)

    def _FirstSunday(self, dt):
        """First Sunday on or after dt."""
        return dt + datetime.timedelta(days=(6-dt.weekday()))

    def dst(self, dt):
        # 2 am on the second Sunday in March
        dst_start = self._FirstSunday(datetime.datetime(dt.year, 3, 8, 2))
        # 1 am on the first Sunday in November
        dst_end = self._FirstSunday(datetime.datetime(dt.year, 11, 1, 1))

        if dst_start <= dt.replace(tzinfo=None) < dst_end:
            return datetime.timedelta(hours=1)
        else:
            return datetime.timedelta(hours=0)
    def tzname(self, dt):
        if self.dst(dt) == datetime.timedelta(hours=0):
            return "PST"
        else:
            return "PDT"

pacific_time = datetime.datetime.fromtimestamp(time.mktime(utc_time.timetuple()), Pacific_tzinfo())

请参阅 datetime 模块文档(包括datetime.tzinfo)。另请参阅第三方模块 pytz,但请注意 pytz 发行版包含许多文件。

DateTimeProperty 模型属性类包含一些功能,如自动使用模型实例的存储日期和时间。这些是模型功能,对于原始 Datastore 值(例如在 Expando 动态属性中的值)不可用。

模型属性:DateTimePropertyDatePropertyTimeProperty

list

由使用受支持数据类型的值组成的值列表。

list 用作 Expando 动态属性的值时,不能是空列表。此限制由列表值的存储方式决定:如果列表属性没有项目,其在 Datastore 中便无法表示。您可以使用静态属性和 ListProperty 类表示属性的空列表值。

模型属性:ListProperty

db.Key

其他 Datastore 实体的键。

注意:键字符串限 1500 字节或更短。

m = Employee(name="Susan", key_name="susan5")
m.put()
e = Employee(name="Bob", manager=m.key())
e.put()

m_key = db.Key.from_path("Employee", "susan5")
e = Employee(name="Jennifer", manager=m_key)

模型属性:ReferencePropertySelfReferenceProperty

blobstore.BlobKey

Blobstore 值的键,上传该值时由 Blobstore 生成。

模型属性:blobstore.BlobReferenceProperty

users.User

拥有 Google 账号的用户。

如果用户更改其电子邮件地址,Datastore 中的 user.User 值不会获得相应更新。因此,我们强烈建议不要将 users.User 存储为 UserProperty 值,因为前者包含电子邮件地址以及唯一 ID。如果用户更改了电子邮件地址,当您将存储的旧 user.User 与新的 user.User 值进行比较时,便会发现它们不匹配。所以请改将 user.User 值的 user_id() 用作用户的固定唯一标识符。

模型属性:UserProperty

class Blob(arg=None)

二进制数据,一种字节字符串。属于内置 str 类型的子类。

Blob 属性未编入索引,不能在过滤条件或排序顺序中使用。

Blob 用于二进制数据(例如图像)。它接受 str 值,但该值以字节字符串存储,且不会编码为文本。对于大型文本数据,请使用 Text 实例。

模型属性:BlobProperty

class MyModel(db.Model):
    blob = db.BlobProperty()

m = MyModel()
m.blob = db.Blob(open("image.png", "rb").read())

在 XML 中,无论 blob 是否包含二进制数据,它们都采用 base-64 编码。

class ByteString(arg)

长度为 1500 个字节或更短的短 blob 值(“字节字符串”)。ByteString 是 str 的子类,它接受未编码的 str 值作为其构造函数的参数。

ByteString 通过 Datastore 编入索引,因此可以在过滤条件和排序顺序中使用。对于长度超过 1500 个字节的字节字符串(未编入索引),请使用 Blob 实例。对于编码的文本数据,请使用 str(短,编入索引)或 Text(长,未编入索引)。

模型属性:ByteStringProperty

class Text(arg=None, encoding=None)

长字符串。属于内置 unicode 类型的子类。

arg:一个 unicodestr 值。如果 argstr,则该值通过 encoding 指定的编码进行解析;如果未指定编码,则通过 ascii 进行解析。请参阅标准编码列表,了解 encoding 的可能值。

不同于值为简单的 strunicode 的实体属性,Text 属性的长度可超过 1500 个字节。但 Text 属性未编入索引,不能在过滤条件或排序顺序中使用。

模型属性:TextProperty

class MyModel(db.Model):
    text = db.TextProperty()

m = MyModel()
m.text = db.Text(u"kittens")

m.text = db.Text("kittens", encoding="latin-1")
class Category(tag)

类别或“标记”。属于内置 unicode 类型的子类。

模型属性:CategoryProperty

class MyModel(db.Model):
    category = db.CategoryProperty()

m = MyModel()
m.category = db.Category("kittens")

在 XML 中,它是一个 Atom Category 元素。

class Email(email)

电子邮件地址。属于内置 unicode 类型的子类。

属性类和值类都不会对电子邮件地址执行验证,它们只存储值。

模型属性:EmailProperty

class MyModel(db.Model):
    email_address = db.EmailProperty()

m = MyModel()
m.email_address = db.Email("larry@example.com")

在 XML 中,它是一个 gd:email 元素。

class GeoPt(lat, lon=None)

由浮点纬度和经度坐标表示的地理点。

模型属性:GeoPtProperty

在 XML 中,它是一个 georss:point 元素。

class IM(protocol, address=None)

即时消息句柄。

protocol 是该即时消息服务的规范网址。一些可能的值:

协议说明
sipSIP/SIMPLE
xmppXMPP/Jabber
http://aim.com/AIM
http://icq.com/ICQ
http://messenger.msn.com/MSN Messenger
http://messenger.yahoo.com/Yahoo Messenger
http://sametime.com/Lotus Sametime
http://gadu-gadu.pl/Gadu-Gadu
未知未知或未指定

address 是句柄的地址。

模型属性:IMProperty

class MyModel(db.Model):
    im = db.IMProperty()

m = MyModel()
m.im = db.IM("http://example.com/", "Larry97")

在 XML 中,它是一个 gd:im 元素。

完全限定网址。属于内置 unicode 类型的子类。

模型属性:LinkProperty

class MyModel(db.Model):
    link = db.LinkProperty()

m = MyModel()
m.link = db.Link("http://www.google.com/")

在 XML 中,它是一个 Atom Link 元素。

class PhoneNumber(phone)

可读的电话号码。属于内置 unicode 类型的子类。

模型属性:PhoneNumberProperty

class MyModel(db.Model):
    phone = db.PhoneNumberProperty()

m = MyModel()
m.phone = db.PhoneNumber("1 (206) 555-1212")

在 XML 中,它是一个 gd.phoneNumber 元素。

class PostalAddress(address)

邮政地址。属于内置 unicode 类型的子类。

模型属性:PostalAddressProperty

class MyModel(db.Model):
    address = db.PostalAddressProperty()

m = MyModel()
m.address = db.PostalAddress("1600 Ampitheater Pkwy., Mountain View, CA")

在 XML 中,它是一个 gd:postalAddress 元素。

class Rating(rating)

由用户提供的对某段内容的评分,评分将为 0 到 100 之间的整数。它是内置 long 类型的子类。该类验证值是否为 0 到 100 之间的整数,如果值无效,则引发 BadValueError

模型属性:RatingProperty

class MyModel(db.Model):
    rating = db.RatingProperty()

m = MyModel()
m.rating = db.Rating(97)

在 XML 中,它是一个 gd:rating 元素。

Property 类

google.appengine.ext.db 提供的所有模型属性类都是基类 Property 的子类,并支持基本构造函数的所有参数。请参阅基类文档,了解这些参数的信息。

google.appengine.ext.db 包提供以下模型属性类:

class BlobProperty(...)

未解析的二进制数据集合。

Blob 数据为字节字符串。对于可能涉及编码的文本数据,请使用 TextProperty

值类型:Blob

class BooleanProperty(...)

布尔值(TrueFalse)。

值类型:bool

class ByteStringProperty(verbose_name=None, ...)

长度为 1500 字节或更短的短 blob 值(“字节字符串”)。

ByteStringProperty 值编入索引,可在过滤条件和排序顺序中使用。

StringProperty 类似,但该值不以任何方式进行编码。字节是按字面存储的。

如果需要 ByteStringProperty,则该值不能为空字符串。

值类型:ByteString

class CategoryProperty(...)

类别或“标记”,即说明性字词或词组。

值类型:Category

class DateProperty(verbose_name=None, auto_now=False, auto_now_add=False, ...)

日期(不带具体时间);请参阅 DateTimeProperty 了解详情。

值类型:datetime.date;内部转换为 datetime.datetime

class DateTimeProperty(verbose_name=None, auto_now=False, auto_now_add=False, ...)

日期和时间。

如果 auto_nowTrue,那么每当模型实例存储在数据存储区中时,属性值就会设为当前时间,覆盖属性的先前值。这有助于跟踪模型实例的“上次修改”日期和时间。

如果 auto_now_addTrue,那么该属性值会设为模型实例首次存储到数据存储区的时间,除非已为属性赋值。这有助于存储模型实例的“创建”日期和时间。

日期时间值以 UTC 时区的形式存储和返回。请参阅 datetime.datetime 了解如何管理时区的讨论。

值类型:datetime.datetime

class EmailProperty(...)

电子邮件地址。

属性类和值类都不会对电子邮件地址执行验证,它们只存储值。

值类型:Email

class FloatProperty(...)

浮点数。

值类型:float

class GeoPtProperty(...)

由浮点纬度和经度坐标表示的地理点。

值类型:GeoPt

class IMProperty(...)

即时消息句柄。

值类型:IM

class IntegerProperty(...)

整数值,最多 64 位。

Python int 值会在存储之前转换为 Python long 值。因此以 int 存储的值将作为 long 返回。

如果分配了一个超过 64 位的 long,系统只会存储 64 位的最低有效位。

值类型:intlong

class LinkProperty(...)

完全限定网址。

值类型:Link

class ListProperty(item_type, verbose_name=None, default=None, ...)

item_type 指定类型的值列表。

在查询中,将列表属性与值进行比较会对列表成员执行测试:list_property = value 测试该值是否出现在列表中的任何位置,list_property < value 测试是否有任何列表成员小于给定值,等等。

一个查询无法比较两个列表值。如果不分别测试成员的每个元素,则将无法测试两个列表是否相同。

item_type 是列表中项目的类型,为 Python 类型或类。列表值中的所有项都必须是给定类型。item_type 必须是某个 Datastore 值类型,并且不能是 list

ListProperty 的值不能为 None。然而,它可以是空列表。如果为 default 参数指定了 None(或未指定 default 参数),则该属性的默认值为空列表。

提示:由于 ListProperty 聚合类型不使用 Property 类,因此 Property 类的功能(例如自动值和验证)不会自动应用于该列表值的成员。如果要使用 Property 类验证成员值,您可以将该类实例化并对该值调用其 validate() 方法。

default 是列表属性的默认值。如果为 None,则默认值为空列表。列表属性定义一个自定义 validator,以防止产生空列表。

请参阅数据建模页面,详细了解列表属性和值。

值类型:指定类型的值的 Python list

class PhoneNumberProperty(...)

可读的电话号码。

值类型:PhoneNumber

class PostalAddressProperty(...)

邮政地址。

值类型:PostalAddress

class RatingProperty()

由用户提供的对某段内容的评分,评分将为 0 到 100 之间的整数。

值类型:Rating

class ReferenceProperty(reference_class=None, verbose_name=None, collection_name=None, ...)

对其他模型实例的引用。例如,引用可能指明在具有属性的模型和由该属性引用的模型之间存在多对一关系。

reference_class 是正被引用的模型实例的模型类。如果已指定,则只能为此属性分配该类的模型实例。如果为 None,则任何模型实例都可以是此属性的值。

collection_name 是要赋予所引用模型类的属性名称。该属性的值是引用该实体的所有实体的 Query。如果未设置 collection_name,则使用 modelname_set(即所引用模型的名称的小写格式,再加上 _set)。

注意:如果同一模型中有多个属性引用同一模型类,则必须设置 collection_name。否则,在生成默认名称时将引发 DuplicatePropertyError

ReferenceProperty 可自动引用模型实例作为属性值以及取消引用:可直接向引用属性分配模型实例,并将使用该模型实例的键。ReferenceProperty 值可当做模型实例使用,当首次以这种方式使用时,将提取数据存储区实体并创建模型实例。未触及的引用属性不会查询不需要的数据。

class Author(db.Model):
    name = db.StringProperty()

class Story(db.Model):
    author = db.ReferenceProperty(Author)

story = db.get(story_key)
author_name = story.author.name

author = db.get(author_key)
stories_by_author = author.story_set.get()

Key 值一样,引用属性值可以引用不存在的数据实体。如果从 Datastore 中删除一个引用的实体,对该实体的引用不会更新。访问不存在的实体时,系统会引发 ReferencePropertyResolveError

删除实体不会删除引用属性所引用的实体。

值类型:db.Key

class SelfReferenceProperty(verbose_name=None, collection_name=None, ...)

对同一类的其他模型实例的引用(请参阅 ReferenceProperty)。

值类型:db.Key

class StringListProperty(verbose_name=None, default=None, ...)

类似于 Python strunicode (basestring) 值的列表属性

值类型:strunicode 值的 Python list

class StringProperty(verbose_name=None, multiline=False, ...)

短字符串。接受长度为 1500 字节或更短的 Python strunicode (basestring) 值。

StringProperty 值编入索引,可在过滤条件和排序顺序中使用。

如果 multilineFalse,则该值不能包含换行符。djangoforms 库可使用此值类型强制区分数据模型中的文本字段和文本区域字段,而且,其他库可使用此值类型实现类似的目的。

如果需要字符串属性,则它的值不能为空字符串。

值类型:strunicode

class TextProperty()

长字符串。

StringProperty 不同的是,TextProperty 值的长度可以超过 1500 字节。但 TextProperty 值未编入索引,不能在过滤条件或排序顺序中使用。

TextProperty 值存储包含文本编码的文本。对于二进制数据,请使用 BlobProperty

如果需要文本属性,则它的值不能为空字符串。

值类型:Text

class TimeProperty(verbose_name=None, auto_now=False, auto_now_add=False, ...)

没有日期的时间。接受 Python 标准库 datetime.time 值;请参阅 DateTimeProperty 了解详情。

值类型:datetime.time;内部转换为 datetime.datetime

class UserProperty(verbose_name=None, auto_current_user=False, auto_current_user_add=False, ...)

重要提示:我们强烈建议您不要存储 UserProperty,因为它包含电子邮件地址和用户的唯一 ID。如果用户更改了其电子邮件地址,当您将其存储的旧 User 与新 User 值进行比较时,它们将无法匹配。

拥有 Google 账号的用户。

如果 auto_current_userTrue,那么每当模型实例存储到数据存储区时,属性值就会设为当前登录用户,覆盖属性的先前值。这有助于跟踪修改模型实例的用户。

如果 auto_current_user_addTrue,属性值会在模型实例第一次存储到数据存储区时设为当前登录用户,除非已为属性赋值。这有助于跟踪创建模型实例的用户,该用户可能不是后来修改它的用户。

UserProperty 不接受默认值。默认值在第一次导入模型类时设置,对于导入缓存,其不一定是当前登录用户。

值类型:users.User