【问题标题】:Add field to App Engine-hosted database将字段添加到 App Engine 托管的数据库
【发布时间】:2012-11-27 13:20:01
【问题描述】:

我目前正在开发一个使用 Google App Engine 托管的网络服务的移动应用程序。

但我面临一个问题。我只想在我的数据库表中添加一个字段。 App Engine 不使用经典的 SQL 语法,而是使用 GQL。所以我不能使用 ALTER TABLE 语句。我怎么能用 GQL 做到这一点?我在网上寻找解决方案,但没有太多帮助。

public MyEntity() {
}

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key idStation;
private String name;
private double longitude;
private double latitude;
private java.util.Date dateRefresh = new Date(); //the field i want to add in DB

所以,现在当我创建一个“MyEntity”对象时,它应该将“dateRefresh”字段添加到数据库中......我这样创建我的对象:

MyEntity station = new MyEntity();
station.setName("test");
station.setLatitude(0);
station.setLongitude(0);
station.setDateRefresh(new Date("01/01/1980"));

DaoFactory.getStationDao().addStation(station);

addStation 方法:

@Override
public MyEntity addStation(MyEntity station) {
    EntityManager em = PersistenceManager.getEntityManagerFactory().createEntityManager();
    try {           
        em.getTransaction().begin();
        em.persist(station);
        em.getTransaction().commit();
    } finally {
        if(em.getTransaction().isActive()) em.getTransaction().rollback();
        em.close();
    }
    return station;
}

永远不会在我的数据库中创建字段“dateRefresh”...

有人帮帮我吗?

提前致谢

【问题讨论】:

    标签: database web-services google-app-engine datastore gql


    【解决方案1】:

    只需将另一个字段添加到您的数据结构中,也许提供一个default 子句,仅此而已。例如,如果您有一个UserAccount

    class UserAccount(db.Model):
        user = db.UserProperty()
        user_id = db.StringProperty()
    

    您可以轻松添加:

    class UserAccount(db.Model):
        user = db.UserProperty()
        user_id = db.StringProperty()
        extra_info = db.IntegerProperty(default=0)
        timezone = db.StringProperty(default="UTC")
    

    然后放手。

    【讨论】:

    • 你能给我更多的细节吗?那是要在 App Engine 上上传的 Python 脚本吗?我正在使用 JPA 和 EntityManager JAVA 对象...
    • Java也是一样,只要加上你需要的字段就可以了。
    【解决方案2】:

    虽然数据存储有点模仿表,但数据是按实体存储的。没有架构或表。

    您需要做的就是更新您的模型类,新实体将与新实体的结构(字段)一起保存。

    但是,旧实体和索引不会自动更新。它们仍然具有与最初写入数据存储区时相同的字段。

    有两种方法可以做到这一点。一种是确保您的代码可以处理缺少新属性的情况,即确保不会引发异常,或者在缺少属性时正确处理异常。

    第二种方法是编写一个小函数(使用 mapreduce 函数)来为每个实体更新新属性的适当值或空值。

    请注意,除非写入实体,否则不会更新索引。因此,如果您添加新的索引属性,则在查询新属性时不会显示旧实体。在这种情况下,您必须使用第二种方法并更新数据存储区中的所有实体,以便为它们编制索引。

    【讨论】:

    • 谢谢。这就是我所理解的。因此,我将该字段添加到我的实体(java 类)中,并尝试从该实体实例化一个对象。但是,当我尝试将此对象持久保存在数据库中时,它会失败,因为该字段不存在于数据库中。但是,当我在本地调试我的网络服务时,新字段存在并且旧实体的值为空......但是当我在 App Engine 上部署我的网络服务时,该字段不在数据库中。谢谢
    • 您正在使用 HRD 权利(您一定是,我认为 GQL 不适用于 CloudSQL)?您可能希望显示您得到的实际代码和错误。您可能误解了该错误,因为如果您要添加新属性,则写入时不会出现问题,前提是新属性已添加到模型中。
    • 将你的代码和错误信息添加到问题中,否则人们无法帮助你。
    • 我做到了。你能帮帮我吗?
    • 我不熟悉 Java API。首先,我不确定您是否需要在声明中分配一个新的 Date() 对象。其次,我会调查 station.setDateRefresh(new Date("01/01/1980"));并检查这是否实际上正确设置了日期。否则,它看起来并不太错。
    猜你喜欢
    • 2016-05-06
    • 2021-03-31
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 2011-07-16
    相关资源
    最近更新 更多