K_Reverter的网页开发记录

要么不做,要么就当作艺术品来做!

导航

失败的尝试-在GAE之中跨app访问数据

    在上次上传了很多数据到GAE上面之后,我开始考虑怎么使用它们,首先要解决跨app访问数据的问题,因为我申请了很多appid,我希望他们能够共享数据,这样我就会轻松很多,要不然我要为每一个数据提供查询接口,然后再其他的app之中访问接口,是很费劲的事情。
    因此我在这个问题上进行了一下尝试和研究,到目前还是在失败状态,因为我是在研究的过程之中开始写的文章,不知道后面能不能研究成功,这个问题虽然在Google文档上没有官方说明,但是我相信是能够做到的,原因如下:
    1.GAE是Google“云”策略的一部分,从“云”的理念来看,应该是能够进行广泛的数据共享;
    2.从GAE DataStore的源码里面我发现很多叫做 _app 的参数,说明从Google的设计来看也是考虑到了这种实现的可能;
    3.google已经推出了remote_api,就算Google暂时不开放_app参数的使用,我通过调用remote_api从原理上也是能走通的。

    因此,我着手研究这个问题,首先使用最简单的办法,通过参数_app来指定访问那个app的数据:

 

class RemoteData3Page(webapp.RequestHandler):
 
def get(self):
  self.response.out.write(
"Fetch remote data only use _app param:")
  places
=db.GqlQuery(("select * from PLA_names where parentCode = '0'"),*{},**{'_app':'dituren-service'}).fetch(100)
  
for place in places:
   self.response.out.write(place.name
+",")

 

    后面的参数_app即指定访问什么哪个app下面的数据,这样使用之后,在本地开发调试我发现返回的数据为空,那显然应该为空,因为在本地找不到名字叫dituren-service的app,我上传到服务器上运行的时候,出现了500错误,去后台一看,是如下错误:
    "adRequestError: app dituren-www cannot access app dituren-service's data"
    说明Google确实从策略上禁止跨app来访问数据,当然,我也没有指望能直接访问,因为Google文档里面没有嘛。

    既然不允许直接访问,那就考虑暂时用remote_api,从Google文档之中找到remote_api的使用方法,按照这个方式来访问数据:

 

def auth_func():
  
return "myusername@gmail.com","mypassword"

class RemoteData1Page(webapp.RequestHandler):
 
def get(self):
  self.response.out.write(
"Fetch remote data use 'google.appengine.ext.remote_api':")
  remote_api_stub
=__import__('google.appengine.ext.remote_api.remote_api_stub').appengine.ext.remote_api.remote_api_stub
  remote_api_stub.ConfigureRemoteDatastore(
"dituren-service"'/data/remote_api',auth_func, "dituren-service.appspot.com")
  places
=db.GqlQuery(("select * from PLA_names where parentCode = '0'"),*{},**{'_app':'dituren-service'}).fetch(100)
  
for place in places:
   self.response.out.write(place.name
+",")

 

    本地运行一下,能显示结果,要是不OK就奇怪了,因为这是按照Google文档使用的,可是上传一运行,还是500错误,去后台一看:
    "No module named tools"
    这似乎说明remote_api的客户端代码是专门为了SDK开发的,只有安装了SDK才能连接,GAE的appspot服务器上缺少一些必要的内容,因此不能运行。
    这让我很困惑,因为GAE的服务器目前能做到的功能仅限于HTTP的连接,因此remote_api服务端实际上也就是通过http实现的,而GAE开发是可以访问http的接口的,为什么会无法访问remote_api呢?
    因此我想到我将remote_api_stub的代码复制一份,改动一下,说不定可以实现,因此就复制了相关文件到app的remote_api下,改几下代码然后上传上去看看,用以下代码来调用:

 

class RemoteData2Page(webapp.RequestHandler):
 
def get(self):
  self.response.out.write(
"Fetch remote data use local remote_api:")
  remote_api_stub
=__import__('remote_api.remote_api_stub').remote_api_stub
  remote_api_stub.ConfigureRemoteDatastore(
"dituren-service"'/data/remote_api',auth_func, "dituren-service.appspot.com")
  places
=db.GqlQuery(("select * from PLA_names where parentCode = '0'"),*{},**{'_app':'dituren-service'}).fetch(100)
  
for place in places:
   self.response.out.write(place.name
+",")

 

    最终还是失败,我的调试过程如下:
    1.首先将google_appengine\google\appengine\ext\remote_api\remote_api_stub.py复制到app根目录的remote_api文件夹,运行还是显示"No module named tools"和上面的错误一样;
    2.将google_appengine\google\appengine\tools\appengine_rpc.py复制到app根目录的remote_api文件夹,并更改remote_api_stub.py之中的调用,显示"module object has no attribute getdefaulttimeout",这让我很困惑,因为GAE的文档之中显示可以使用urllib和socket,为什么我只是将相应的代码移动到我的app目录下,就会出现连类的方法都不存在的情况呢?;
    3.我考虑将appengine_rpc中使用到socket的地方删除,因为我觉得好像也不是很重要,可是删除之后,显示从服务器下载到的内容为空,也就是更加不知道是怎么回事了;
    4.我将appengine_rpc中进行http访问的代码更改为使用urlfetch,也能够跑起来,可是urlfetch不能指定cookie,而要访问remote_api必须要使用cookie,所以每次总是获取到302的状态码;
    5.我考虑将remote_api的用户验证关闭,觉得这样应该就可以不用Cookie访问了,可是我在app.yaml之中将login: admin去掉之后,服务端返回一个文本,说什么这个服务只允许登录后的管理员使用,实在太晕了,实际上那个"login :admin"原来是多余的……

    经过以上折腾之后,我再也没有耐心了,因此宣告失败。假如有谁了解怎样方便在APP之间共享数据,希望能分享一下,我暂时不研究这个了。

posted on 2009-03-20 19:09  K_Reverter  阅读(841)  评论(5编辑  收藏  举报