12

I've been reading between the lines and trying to interface dev_appserver.py with the new 'non-legacy' google cloud datastore emulator.

My main motivation is to integrate my appengine projects with my google cloud dataflow pipeline while I am developing on my local machine.

This is the procedure to setup the integration, as far as I understand:

  • Install the googledatastore library with pip (you may need to force an upgrade of six with easy_install particularly if you are using system python El Capitan)
  • Using the google cloud sdk tools run the google cloud datastore emulator:

    gcloud beta emulators datastore start --no-legacy
    
  • In the terminal where dev_appserver will run the following command to set datastore environment variables:

    $(gcloud beta emulators datastore env-init --no-legacy)
    
  • If the project id in app.yaml does not match the currently select project id in the gcloud tools set the following environment variable in the same shell:

    export DATASTORE_USE_PROJECT_ID_AS_APP_ID=true
    
  • Run dev_appserver.py and navigate to http://localhost:8000/datastore which should let you navigate the emulator's datastore data.

However this does not work so smoothly when I navigate to the url I get:

BadArgumentError: Could not import googledatastore.
This library must be installed with version >= 4.0.0.b1 to use the Cloud Datastore 
API.

This is strange because if I open a python shell and run import googledatastore no error occurs.

If I dig a bit deeper and instrument the import code in dev_appserver and log the error here I get the following traceback:

Traceback (most recent call last):
  File "/usr/local/google-cloud-sdk/platform/google_appengine/google/appengine/datastore/datastore_pbs.py", line 52, in <module>
    import googledatastore
  File "/Library/Python/2.7/site-packages/googledatastore/__init__.py", line 21, in <module>
    from . import helper
  File "/Library/Python/2.7/site-packages/googledatastore/helper.py", line 25, in <module>
    from google.datastore.v1beta3 import entity_pb2
ImportError: No module named datastore.v1beta3 

I also have no issue importing google.datastore.v1beta3 in a regular python shell.

Even stranger if I run PYTHONINSPECT=x dev_appserver.py app.yaml and drop out into the shell executing these imports runs without error. Perhaps there is something odd going on with the python path while dev_appserver.py is starting?

Can anybody tell me how to get this feature working?

UPDATE: I reproduced this problem on ubuntu 14.04 (system python 2.7.6, pip 8.1.2 via easy_install, gcloud-sdk 118.0.0, app-engine-python 1.9.38) as well as OS X (gcloud sdk 114.0.0, app-engine-python 1.9.38, system python 2.7.10).

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
Frank Wilson
  • 3,192
  • 1
  • 20
  • 29
  • FWIW, GAE SDK 1.9.38 is affected by a bug causing import errors similar to yours, see http://stackoverflow.com/questions/37755195/importerror-no-module-named-webapp2-after-linux-sdk-upgrade-1-9-35-1-9-38. I'd suggest trying with 1.9.40 (latest now) which has the fix. – Dan Cornilescu Aug 05 '16 at 03:39
  • @zenlambda did you ever get this to work? – ThomasD Oct 03 '16 at 22:27
  • 1
    This is still occurring as of this post. [I've posted an issue on the Public Issue Tracker for App Engine](https://code.google.com/p/googleappengine/issues/detail?id=13589), and folks can follow there for a solution. – Nick Feb 28 '17 at 20:52
  • I get the same error. Have you found any solution? – Sefran2 Apr 27 '17 at 10:51

3 Answers3

5

Heads up folks,

Using google cloud datastore emulator with dev_appserver is now available! (link)

Update Google Cloud SDK, then run dev_appserver with '----support_datastore_emulator'.

This feature is in Beta, welcome to try it! We are actively collecting feedback.

Kai Wang
  • 179
  • 1
  • 2
  • on a slightly related note, i am running into [this](https://stackoverflow.com/q/57758261/720508) error while importing "java.lang.OutOfMemoryError: GC overhead limit exceeded" locally, any thought on how to fix ? is there any place where you are actively collecting feedback? – bool.dev Apr 30 '20 at 07:15
3

Actually gcloud datastore emulator and dev_appserver points to two different endpoints. the localhost:8000 is the default dev_appserver admin console, while the datastore emulator have a different console url which could be found in print outs when it starts.

I assume the admin console you are accessing belongs to dev_appserver, then the issue should be within dev_appserver. Could you attach the code snippet(if there is any) using datastore api in dev_appserver? BTW it should be gcloud.datastore instead of appengine.ext.(n)db talking to gcloud datastore-emulator.

Also, I'm curious what would happen if you do not start datastore-emulator with '--no-legacy', or even do not start datastore-emulator but just start dev_appserver?

Kai Wang
  • 179
  • 1
  • 2
  • 1
    > it should be gcloud.datastore instead of appengine.ext.(n)db talking to gcloud datastore-emulator. Unfortunately using appengine.ext.ndb with the standalone datastore emulator is precisely what I want to do, to avoid rewriting code while doing integration tests with newer apps. It thought I had spotted functionality that appears to allow dev_appserver to use an external datastore emulator, it just transpires that it does not seem to work yet. – Frank Wilson Jul 29 '16 at 09:37
  • 2
    `using appengine.ext.ndb with standalone datastore emulator` is not supported at this moment. Currently gcloud.datastore is the only option, as stated on this page https://cloud.google.com/datastore/docs/tools/datastore-emulator. – Kai Wang Jul 29 '16 at 17:28
  • The datastore emulator doesn't appear to show anything but "Ok" when I visit the only localhost: output visible when running it. – Nick Feb 28 '17 at 20:55
  • @KaiWang: any update about the `BadArgumentError: Could not import googledatastore` issue? – Sefran2 Apr 27 '17 at 12:32
  • This BadArgumentError is likely because of an environment variable called "DATASTORE_PROJECT_ID" in your shell, try removing it. Generally, to connect dev_appserver to the Cloud Datastore Emulator, please check this documentation: https://cloud.google.com/appengine/docs/standard/python/tools/migrate-cloud-datastore-emulator – Kai Wang Jul 02 '18 at 21:17
3

We recently ran into this same issue. One thing to look at is the output of the command:

(gcloud beta emulators datastore env-init --no-legacy)

The problem we had was that when we ran the emulator the emulator was choosing say port 8607 but the env-init method was returning a different port 8328.

So, what I would recommend is to start the emulator and see what port it is running on:

[datastore] Aug 04, 2016 3:50:50 PM com.google.appengine.tools.development.AbstractModule startup
[datastore] INFO: Module instance default is running at http://localhost:8607/
[datastore] Aug 04, 2016 3:50:50 PM com.google.appengine.tools.development.AbstractModule startup
[datastore] INFO: The admin console is running at http://localhost:8607/_ah/admin

In this case 8607 and then fire off the env-init method to get the syntax but validate the port. In our case with the above server running the env-init returns 8328

$ (gcloud beta emulators datastore env-init)
export DATASTORE_DATASET=my-app
export DATASTORE_EMULATOR_HOST_PATH=localhost:8328/datastore
export DATASTORE_EMULATOR_HOST=localhost:8328
export DATASTORE_HOST=http://localhost:8328
export DATASTORE_PROJECT_ID=my-app

So change this to the correct port:

export DATASTORE_DATASET=my-app
export DATASTORE_EMULATOR_HOST_PATH=localhost:8607/datastore
export DATASTORE_EMULATOR_HOST=localhost:8607
export DATASTORE_HOST=http://localhost:8607
export DATASTORE_PROJECT_ID=my-app

Then use this where your project is running and you should be good to go. This is what fixed it for us. Hope that helps!

djneely
  • 1,074
  • 13
  • 25
  • update 2021: --no-legacy is no longer supported: `ERROR: (gcloud.beta.emulators.datastore.env-init) unrecognized arguments: --no-legacy` – belwood Jan 23 '21 at 17:56