【问题标题】:Cloud Datastore API - php - GqlQuery - "SELECT * FROM kind_name WHERE __key__"Cloud Datastore API - php - GqlQuery - “SELECT * FROM kind_name WHERE __key__”
【发布时间】:2014-11-07 15:28:00
【问题描述】:

我在 GAE:php 运行时上有一个应用程序,我正在使用 Google Cloud Datastore API 从我的 PHP 应用程序连接到 Datastore。

我的问题:

如何使用键查询我的数据库,类似于 Sql 中的"SELECT * FROM table_name WHERE id <= 1410611039"

我的代码:(我看到人们正在使用这种查询字符串语法并且它适用于他们)

$gql_query = new Google_Service_Datastore_GqlQuery();
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = KEY('notification', 1410611039)");

我得到的部分错误是 Fatal error: Uncaught exception ... (400) Disallowed literal: KEY...

我的数据存储控制台视图:

在我将 WHERE __key__ = KEY('notification', 1410611039) 附加到 query_string 之前,一切都很好。

【问题讨论】:

  • Cloud Datastore GQL 与 App Engine GQL 略有不同。不过,我不确定这里的确切问题:您是否尝试过不带引号的 notification
  • 是的,我刚试过notification 不带引号,但仍然是同样的错误。不幸的是,没有关于如何制作 Gql 字符串的 Datastore API 指南。我认为KEY('kind', 'name/id') 是一种制作数据存储密钥的方法,但它不能通过 API 工作。

标签: php google-app-engine gql google-cloud-datastore


【解决方案1】:

键在 Cloud Datastore GQL 中被视为文字,需要特殊处理。

如果用户将在运行时提供值,我们建议使用参数绑定。这有助于防止恶意行为,例如注入攻击。

有两种方法可以做到这一点;都以键值开头:

$key_path_element = new Google_Service_Datastore_KeyPathElement();
$key_path_element->setKind('notification');
$key_path_element->setId(1410611039);

$key = new Google_Service_Datastore_Key();
$key.setPath([$key_path_element]);

$key_value = new Google_Service_Datastore_Value();
$key_value->setKeyValue($key);

$key_value 然后可以用作命名参数:

$gql_query = new Google_Service_Datastore_GqlQuery();
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = $theKey");

$name_arg = new Google_Service_Datastore_GqlQueryArg();
$name_arg->setName("theKey");
$name_arg->setValue($key_value);

$gql_query->setNameArgs([$name_arg]);

或作为位置参数:

$gql_query = new Google_Service_Datastore_GqlQuery();
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = @1");

$number_arg = new Google_Service_Datastore_GqlQueryArg();
$number_arg->setValue($key_value);

$gql_query->setNumberArgs([$number_arg]);

如果没有将用户提供的输入添加到查询中,另一种选择是在请求中明确允许文字:

$gql_query = new Google_Service_Datastore_GqlQuery();
$gql_query->setQueryString("SELECT * FROM notification WHERE __key__ = KEY('notification', 1410611039)");
$gql_query->setAllowLiteral(true);

这里有一些关于argument binding 的更多详细信息,这里是full GQL reference

【讨论】:

  • 感谢您的清晰解释。所以,我错过了$gql_query->setAllowLiteral(true);。我的问题是我不知道“键被认为是文字”,老实说,由于我的英语水平,我仍然不知道这意味着什么!如果有人能给我一个线索,那就太好了。
【解决方案2】:

我在使用 Java Datastore API 时遇到了同样的问题。 Java 中的解决方案如下所示:

datastore = DatastoreOptions.builder()
.authCredentials(AuthCredentials.createApplicationDefaults())
.build()
.service();
String id = "asdf123";
Query<Entity> query = Query.gqlQueryBuilder(
    Query.ResultType.ENTITY, 
    "SELECT * FROM Task WHERE id = '"+id+"'")
    .allowLiteral(true)
    .build();
QueryResults<Entity> result = datastore.run(query);
while(result.hasNext()){
    Entity temp = result.next();
    //(...)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2014-01-27
    相关资源
    最近更新 更多