基于 Python 的 GAE 数据建模要点

214 阅读5分钟

基于 Python 的 GAE 数据建模要点

Task 模型类:

class Task(db.Model1):

    name = db.stringProperty(required=True)

    description=db.stringProperty() 

    start_date = db.DateProperty(required=True) 
    
    due_date=db.DateProperty()

    end_date=db.DateProperty() 
    
    tags=db.StringListproperty()

首先要注意的是 Task 模型类扩展了 db.Model class。Model 类(在 google.appeng.ext.db 模块中)是数据建模 API 中提供的三个内置模型类之一。另外两个类分别命名为 expandpolyModel

Model类是三个模型类中最严格和最正式的。Model 定义了一个结构化数据模型,该模型具有一组定义良好的属性,其中每个属性的数据类型都在设计时声明。在某些方面,定义 Model 类或从它继承类似于定义传统的数据库模式。

Task 类是一个 Model 类型,它定义了六个属性。六个属性中的每一个都有一个定义良好的类型,其中类型是使用 Property 类的子类定义的。Python 包装器(SDK 和 API)定义并支持一组属性数据类型。相应的类集有助于在数据模型中定义属性。属性类定义属性值的数据类型。它还定义了如何验证值并将其存储在数据存储区中。例如,stringProperty 类表示长度不超过500个字符的所有 Python strunicode 值类型。

DatePropertyDateTimeProperty 的子类型,只表示日期和时间值的日期部分。

StringListProperty 表示字符串值的列表。

常见的支持类型和相应的类

下表总结了最常见的支持类型和相应的类。

值类型属性类排序顺序附加说明定义数据类型
str,UnicodeStringPropertyUnicode< 500个字符。str作为ASCII进行排序No
db.TextTextPropertynot orderable长字符串(> 500个字符)Yes
db.ByteStringByteStringPropertybyte order< 500字节.ByteString 扩展 str 并表示未编码的字节字符串。Yes
db.BlobBlobPropertynot orderable字节字符串最大为1MB。Yes
BoolBooleanPropertyFalse<TrueNo
int,long(64 bit)IntegerPropertyNumericNo
FloatFloatPropertyNumeric如果 float 和 int 放在一起,则 int < float,这意味着5 < 4.5。No
datetime.datetimeDateTimeProperty, DateProperty, TimePropertychronologicalNo
List of supported value typesListProperty, StringListProperty如果是 ASC,按最小元素; 如果是 DESC,按最大元素No
NullPython 'None'.No

该列中的“ No”值意味着数据类型不是在 GAE Python API 中定义的,而是在 Pytbon 语言及其标准库中定义的。

其他类型来定义实体键

除了表中列出的常见数据类型之外,还支持其他类型来定义实体键,并建模涉及电子邮件、即时通讯、邮政地址和电话号码的谷歌帐户和典型通信身份。还定义了类来对地理点、标记或评级值进行建模。

数据存储密钥是使用 google.appengineering.ext.db 模块中的 Key 类建模的。

获得支持的其他类型如下:

  • Google accounts-users.User
  • Email-db.Email
  • IM-db.IM(Instant Messaging ID)
  • Postal address-db.PostalAddress
  • Phone number-db.PhoneNumber
  • Category-db.Category
  • Link-db.Link
  • Rating-db.Rating
  • Geographical point-db.GeoPt

虽然在受支持类型的帮助下,Model 类允许您精确定义所需的数据模式,但是模型中的灵活性有时很重要

您可能还记得,基础数据存储区在架构或数据类型方面没有强加任何限制。换句话说,您可以根据需要添加属性,而且属性集可以在同一类型的两个实体之间变化。此外,两个实体可以选择为同一属性存储不同的数据类型。为了对这种动态和灵活的模式进行建模,GAE Python API 定义了一个名为 Expado 的 model类。

GoogleAppEngine 还提供了一个与数据存储不同的 Blobstore。Blobstore 服务允许您存储对数据存储来说太大的对象。Blobstore 中的一个 blob 由一个 Blobstore 标识。BlobKey.BlobKey (s)可以按字节顺序排序

扩展

属性可以是两种类型:

  • 固定属性

  • 动态属性

定义为模型类属性的属性是固定属性。作为属性添加到模型实例的属性是动态属性。

模型实例而不是类作为实体持久存在。

模型类的实例继承自 Expandomodel 类,它可以同时具有固定和动态属性。这允许两个作为实体持久化的模型实例对同一属性具有不同的数据类型。它还可能使一个实例添加一个属性(比如 new_tribute) ,而另一个实例根本不添加这个属性。实例可以包含新属性,但不对其进行设置。

我重构了从 Expando 继承的 Task 模型类。

新 Task 类及其实例的代码片段如下:


import datetime

from google.appengine.ext import db 

class Task(db.Expando):

    name=db.stringProperty(required=True) 
    
    description = db.stringProperty()

    start_date=db.DateProperty(required=True) 
    
    due_date=db.DateProperty()

    end_date= db.DateProperty() 
    
    tags =db.stringListproperty()

    t1 = Task(name="task1", start_date=datetime.datetime.now().date()) 
    
    t1.description="this is task 1"

    t1.tags = ["important", "sample"] 
    
    t1.collaborator="John Doe"

    t2 = Task(name="task2", start_date=datetime.datetime.now().date()) 
    
    t2.description = "this is task 2"

    t2.tags = ["important", "sample"]

    t2.resources = ["resource1", "resource2"]

这个例子是不言自明的,并且展示了灵活的 Expando 模型的强大功能。

不过,灵活性是有代价的。动态属性不像固定属性对应物那样进行验证。

PolyModel

建模 API 提供了另一种模型类变体,允许您定义多态行为。

PolyModel 类(在 google.appeng.ext.db.PolyModel 模块中)允许您在一组模型类之间定义继承层次结构。一旦通过类继承建立了层次结构,就可以查询类类型,并在结果集中获得类及其子类的合格实体。

为了说明这一点,我再次修改了 Task 类。我重构了 Task 类以扩展 PolyModel 类。然后,我创建了 Task 类的两个子类。

子类是 PersonualTaskTeamTask,它们分别代表各个所有者和组的任务。示例代码如下:

from google.appengine.ext import db

from google.appengine.ext.db

import polymodel


class Task(polymodel.PolyModel):

    name=db.stringProperty(required=True)

    description = db.stringProperty()

    start_date = db.DateProperty(required=True)
    due_date = db.DateProperty()

    end_date = db.DateProperty()
    tags = db.StringListProperty()

class IndividualTask(Task):

    owner = db.stringProperty()

class TeamTask(Task):

    team_name = db.stringProperty()

    collaborators = db.stringListProperty()

现在,如果查询 Task 实体,我将添加结果集中的 Task 实体。

一旦您了解了应用程序引擎中可用的查询机制,您将更好地理解这一点。接下来,我将介绍查询和索引。

在应用程序引擎 GEA下进行查询和建立索引 - 掘金 (juejin.cn)


本文正在参加「金石计划 . 瓜分6万现金大奖」