Is it possible to use GQL from a java appengine application?
I've seen several references to GqlQuery object in various packages here and there, but I see nothing about how to use it from an AppEngine application.
Is it possible? What maven package should I use for it? If it's available, is it stable -or- pre-release?
Thanks, Chad
I think it is possible. I did some googling and I have noted here what I found.
Disclaimer: I have tested none of this and I, like Andrei, would strongly recommend using Objectify.
You can get a datastore instance from the API. From https://cloud.google.com/datastore/docs/datastore-api-tutorial:
// Create an authorized Datastore service using Application Default Credentials.
private final Datastore datastore = DatastoreOptions.defaultInstance().service();
You would need at least the following Maven package. Like it says it is in Beta.
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-datastore-protobuf</artifactId>
<version>v1beta2-rev1-4.0.0</version>
</dependency>
You could then do a GQL query like this.
From https://cloud.google.com/datastore/docs/concepts/gql:
// import static com.google.api.services.datastore.client.DatastoreHelper.*;
GqlQuery.Builder query = GqlQuery.newBuilder().setQueryString("SELECT * FROM Person");
RunQueryRequest request = RunQueryRequest.newBuilder().setGqlQuery(query).build();
RunQueryResponse response = datastore.runQuery(request);
List<Entity> results = new ArrayList<Entity>();
for (EntityResult entityResult : response.getBatch().getEntityResultList()) {
results.add(entityResult.getEntity());
}
Related
I am trying to write a JPA query to get the type for a particular entity, given the id of the entity. I have an abstract class Account, and concrete subclasses CustomerAccount and AdministratorAccount. The id is an attribute of the Account, so I am trying to construct a query to return the Type (i.e. foo.bar.CustomerAccount) given the ID of the account.
I tried the following:
String sql = "SELECT TYPE(a) from Account a where a.id = :userId";
But that doesn't seem to work. Any ideas? I'm using the google app engine jpa implementation (datanucleus) if that helps.
Firstly, FWIW you are using Google's JPA plugin which just happens to use some ancient jars provided by the DataNucleus project. You are not using DataNucleus JPA.
Secondly, the datastore "GAE/Datastore" and Google's JPA plugin are not likely to support JPQL "TYPE" since that came along after their plugin was developed.
Finally, you maybe would get the info you want in a more efficient way by just doing
Object obj = em.find(Account.class, id);
Class type = obj.getClass();
since this also inspects the L1/L2 caches
I came to know GAE cloud endpoints yesterday. From that time I am trying to generate APIs for my current web application. I am using JPA2.0, I chose one of my entity classes right clicked on it and then "generate Google endpoint class" . So now I have another class for this entity with #API annotations, etc.
But the problem is after deploying the app when I go to : https://developers.google.com/apis-explorer/?base=https://myAppId.appspot.com/_ah/api#p/
the services tab is empty. Same thing when I check it locally(Image below)
You need to Generate Cloud Endpoints Library (in Eclipse, right click on the Project, it's under Google) as well.
I had similar issue and it was caused by missing public attribute in methods.
#Api
public class MyApi {
#ApiMethod
void myMethod() { }
}
caused that I saw no methods. While added
#Api
public class MyApi {
#ApiMethod
public void myMethod() { }
}
methods started to be visible.
1.Login appengine
https://appengine.google.com/
2.Click the [Version] link in a Main category
3.Select your version and [Make Default] button
4.You can access the api explorer
https://myAppId.appspot.com/_ah/api/explorer
Best Regard.
I actually managed to resolve the above issue. So I had a web application existing and I thought I could just add annotations to it and have the APIs represented for it after deployment. But I realized that I had to start from scratch by creating an android app and then generate the back-end for that app and add my classes there. It now works. Thank you.
Points to remember before working on endpoints :
Need to create an endpoint client library before running your project.(In Eclipse : Project -> Right click -> Google -> Generate cloud endpoints library)
Check whether you are using latest Google Plugin or not. Because files required by endpoints will be executed from the plugin. If you are not able to generate the endpoint library. problem is with the plugin .Try updating it.
Endpoints will work only on default versions. Make sure that you made your version default.
finally try loading http://myApp.appspot.com/_ah/api/explorer. Everything should be fine now.
I have a simple GAE application using JPA and eclipse plugin for GAE (sdk version 1.7.2).
I only have one simple entity mapped wit 2 properties : 1 Key key ; and one String name.
I have created only one class (taken from the "Datastore Callbacks" documentation of gae)
public class PostPutCallbacks {
static Logger logger = Logger.getLogger(PostPutCallbacks.class.getName());
#PostPut
public void collectSample(PutContext context) {
logger.fine("Finished putting " + context.getCurrentElement().getKey());
}
}
The database callback is not called.
I tried with several other annotations (#PrePut #PreGet) but they still didn't work .
I've also tried with the Datastore low leve API and the callback is still not called.
I searched the web to see if there is a configuration besides the annotation processing jar manualy added for eclipse but I didn't find anything..
Can anyone give me a hint?
I want to provide more information in this thread. If you are unable to see the datastore callbacks being triggered. Try this procedure as documented. You need to do some simple project set up at Eclipse in order to make it work. Hope this helps.
I jumped a little fast to stackoverflow..I had to restart eclipse and it worked
I would like to make a backup of all user data in the datastore. My application is using the new namespace feature to provide multi tenanting on a per user basis (as per the example in the docs).
The bulk loader needs the namespace for each customer to download the data. I don't keep a list of users, so I can't generate the namespaces. Is there a method of detecting all the currently used namespaces?
Since SDK 1.4.0 you can use Metadata Queries:
from google.appengine.ext.db import metadata
for ns in metadata.get_namespaces():
print "namespace: '%s'" % ns.namespace_name
For NDB the import is slightly different:
from google.appengine.ext.ndb import metadata
There is also now a get_namespaces() function:
from google.appengine.ext.db import metadata
namespaces = metadata.get_namespaces()
get_namespaces() returns a list of Namespace objects. The docs also note that "metadata queries that fetch information on namespaces, kinds, and properties are generally slow to execute."
Using ndb
from google.appengine.ext.ndb import metadata
all_namespaces = [ns for ns in metadata.get_namespaces()]
Using datastore
Per Datastore Metadata:
query = client.query(kind='__namespace__')
query.keys_only()
all_namespaces = [entity.key.id_or_name for entity in query.fetch()]
There's no API to get a list of namespaces. You must keep a record of the ones you use. I use a model specifically for this.
The CherryPy web server can supposedly be deployed in the Google App Engine.
Who has done it, and what was the experience like?
What special effort was required (configuration, etc.)?
Would you recommend it to others?
The article is a good example but its slightly out of date now as the patch is no longer required, the latest version of Cherrypy should run without it, I've gotten the sample below running in the development environment.
I've included cherrypy inside a zip file as the google app engine has a limit of one thousand files per application, it also makes it easier to deploy.
I'm also using the cherrypy dispatch handler to route the request.
import sys
sys.path.insert(0, 'cherrypy.zip')
import cherrypy
import wsgiref.handlers
class Root:
exposed = True
def GET(self):
return "give a basic description of the service"
d = cherrypy.dispatch.MethodDispatcher()
conf = {'/':
{
'request.dispatch': d
}
}
app = cherrypy.tree.mount(Root(), "/",conf)
wsgiref.handlers.CGIHandler().run(app)
So far I've not come across any particular issues but I have read some people have had issues with sessions.
See boodebr.org article (missing, but here on the Wayback machine) It works for me.
If you are looking for an example, look for the condition that accepts ServerMode.GAE in ServerInterface.auto in this example.
There is a good article on how to do this over here now here. I haven't actually tried this yet, I stuck with django on App Engine, but it seems to be a solid example.