代码之家  ›  专栏  ›  技术社区  ›  Nick Heiner

谷歌应用引擎:“当文件已经存在时无法创建文件”

  •  2
  • Nick Heiner  · 技术社区  · 14 年前

    我在Windows7上运行谷歌应用引擎devserver 1.3.3。

    通常,此方法工作正常,但这次出现了一个错误:

    def _deleteType(type):
        results = type.all().fetch(1000)
        while results:
            db.delete(results)
            results = type.all().fetch(1000)
    

    错误:

      File "src\modelutils.py", line 38, in _deleteType
        db.delete(results)
      File "C:\Program Files\Google\google_appengine\google\appengine\ext\db\__init__.py", line 1302, in delete
        datastore.Delete(keys, rpc=rpc)
      File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore.py", line 386, in Delete
        'datastore_v3', 'Delete', req, datastore_pb.DeleteResponse(), rpc)
      File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore.py", line 186, in _MakeSyncCall
        rpc.check_success()
      File "C:\Program Files\Google\google_appengine\google\appengine\api\apiproxy_stub_map.py", line 474, in check_success
        self.__rpc.CheckSuccess()
      File "C:\Program Files\Google\google_appengine\google\appengine\api\apiproxy_rpc.py", line 149, in _WaitImpl
        self.request, self.response)
      File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_file_stub.py", line 667, in MakeSyncCall
        response)
      File "C:\Program Files\Google\google_appengine\google\appengine\api\apiproxy_stub.py", line 80, in MakeSyncCall
        method(request, response)
      File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_file_stub.py", line 775, in _Dynamic_Delete
        self.__WriteDatastore()
      File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_file_stub.py", line 610, in __WriteDatastore
        self.__WritePickled(encoded, self.__datastore_file)
      File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_file_stub.py", line 656, in __WritePickled
        os.rename(tmpfile.name, filename)
    WindowsError: [Error 183] Cannot create a file when that file already exists
    

    我做错什么了?这次怎么会失败,但通常不会?

    更新 我重新启动了devserver,当它重新联机时,数据存储是空的。

    2 回复  |  直到 14 年前
        1
  •  3
  •   Alex Martelli    14 年前

    不幸的是,1.3.3远远落后于我,我无法查看它的源代码并尝试准确地诊断您的问题-SDK没有1.3.3版本标记,我无法猜测 datastore_filestub.py 是1.3.3。是否可以升级到当前版本1.3.5,然后重试?不建议运行旧版本(尤其是2+版本),因为它们可能与Google实际服务器上的实际可用版本有点不同步(和/或在更高版本中修复了错误)。总之…

    在Windows上, os.rename 如果目的地存在,就不起作用了——但是我看到的修改很小心地抓住了 OSError 这样的结果( WindowsError 从中派生),删除现有文件,然后再次尝试重命名。所以我不知道什么可以解释你的bug——如果你运行的sdk的源代码有这样一个仔细的安排,我认为它们是这样的。

    另外,我建议 --use_sqlite (参见尼克·约翰逊的博客 here )代替您的sdk数据存储的文件存根-它只是看起来更有意义!-)

        2
  •  1
  •   wescpy    14 年前

    (免责声明:我不是在回答您的问题,而是帮助您优化正在运行的代码)

    您的代码似乎正在大量删除对象。在sdk/dev服务器中,可以使用此命令更快更方便地清除数据存储区:

    $ dev_appserver.py -c helloworld
    

    现在,也就是说,如果您想要擦除整个SDK数据存储区。如果没有,那么当然,不要使用它。-)

    更重要的是,如果您将查询更改为如下类型,您可以使代码运行更快,并且在生产环境中使用更少的CPU:

    results = type.all(keys_only=True).fetch(SIZE)
    

    这与您的工作原理相同,只是它只提取键,因为您不需要从数据存储中检索完整的实体来删除它们。另外,您的代码当前正在设置 SIZE=1000 ,但您可以使其更大,特别是如果您知道您的系统中有多少个实体…1.3.1中提升了1000个结果限制。 http://bit.ly/ahoLQp

    一个小麻烦…尽量不要使用 type 作为变量名…这是Python中最重要的导入对象和内置/工厂函数之一。如果这样做,您的代码可能会表现得很奇怪——在您的情况下,它只是稍微好一些,因为您在一个函数/方法中,但是作为一个全局变量,这不会是真的。

    希望这有帮助!