为什么manage.py syncdb连接不上Google Cloud SQL数据库?

4

最近我在对Google App Engine上的应用进行更新时,正在更新数据库:

SETTINGS_MODE='prod' ./manage.py syncdb

上次运行时这个代码可以正常工作,但现在出现了以下错误:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 285, in execute
    output = self.handle(*args, **options)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 415, in handle
    return self.handle_noargs(**options)
  File "/c/clients/green_rentals/code/green-rental/south/management/commands/syncdb.py", line 92, in handle_noargs
    syncdb.Command().execute(**options)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 285, in execute
    output = self.handle(*args, **options)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 415, in handle
    return self.handle_noargs(**options)
  File "/Library/Python/2.7/site-packages/django/core/management/commands/syncdb.py", line 57, in handle_noargs
    cursor = connection.cursor()
  File "/Library/Python/2.7/site-packages/django/db/backends/__init__.py", line 159, in cursor
    cursor = util.CursorWrapper(self._cursor(), self)
  File "/c/downloads/python/google_appengine/google/storage/speckle/python/django/backend/base.py", line 263, in _cursor
    if not self._valid_connection():
  File "/c/downloads/python/google_appengine/google/storage/speckle/python/django/backend/base.py", line 258, in _valid_connection
    return super(DatabaseWrapper, self)._valid_connection()
AttributeError: 'super' object has no attribute '_valid_connection'

我尝试将Google App Engine SDK更新到最新版本(1.8.8),并尝试通过oauth重新验证身份(已成功)。但仍然收到相同的消息。有任何线索吗?

提前感谢您的帮助!

编辑:

看起来我用于数据库连接的设置最近已更改。我过去使用的是:

DATABASES = {
    'default': {
        'ENGINE': 'google.appengine.ext.django.backends.rdbms',
        'INSTANCE': 'project-id:instance-id',
        'NAME': 'name',
    }
}

但是现在的建议是:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '/cloudsql/your-project-id:your-instance-name',
        'NAME': 'database-name',
        'USER': 'mysql-user',
    }
}

更新后,我现在遇到了一个新的错误:
Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 285, in execute
    output = self.handle(*args, **options)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 415, in handle
    return self.handle_noargs(**options)
  File "/c/clients/green_rentals/code/green-rental/south/management/commands/syncdb.py", line 89, in handle_noargs
    db.connection_init() 
  File "/c/clients/green_rentals/code/green-rental/south/db/mysql.py", line 180, in connection_init
    cursor = self._get_connection().cursor()
  File "/Library/Python/2.7/site-packages/django/db/backends/__init__.py", line 159, in cursor
    cursor = util.CursorWrapper(self._cursor(), self)
  File "/Library/Python/2.7/site-packages/django/db/backends/__init__.py", line 129, in _cursor
    self.ensure_connection()
  File "/Library/Python/2.7/site-packages/django/db/backends/__init__.py", line 124, in ensure_connection
    self.connect()
  File "/Library/Python/2.7/site-packages/django/db/utils.py", line 99, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/Library/Python/2.7/site-packages/django/db/backends/__init__.py", line 124, in ensure_connection
    self.connect()
  File "/Library/Python/2.7/site-packages/django/db/backends/__init__.py", line 112, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/Library/Python/2.7/site-packages/django/db/backends/mysql/base.py", line 435, in get_new_connection
    conn = Database.connect(**conn_params)
  File "/Library/Python/2.7/site-packages/MySQLdb/__init__.py", line 81, in Connect
    return Connection(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/MySQLdb/connections.py", line 187, in __init__
    super(Connection, self).__init__(*args, **kwargs2)
django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/cloudsql/your-project-id:your-instance-name' (2)")

(其中your-project-id:your-instance-name已经相应更改)
3个回答

10

介绍

我将在这里留下一个更详细的答案,为那些也被这问题困扰的人提供帮助。我意识到已经有另一个回答被接受了,但希望这个能对其他人有所帮助。我们目前使用的是 Django 1.6。

基本上可以归结为:Google App Engine 的 Django <-> CloudSQL 文档 目前已经过时。它们使用 OAuth2 连接机制,在最佳情况下比较笨拙,如果你正在使用来自无头 Vagrant/虚拟机中的 syncdb 管理命令,则需要启用 JavaScript 才能检索令牌(除非你试着玩弄 gflags 库的全局状态,但这是另一天的故事),在命令行上显然会很麻烦(我相信只有 elinks 支持 CLI JS,并且 Ubuntu 存储库版本不包括 js 支持..)

在 Google App Engine Web 控制台中设置

如果你访问此链接,你将找到有关连接实例的新方法的说明。这是通过在 Web 控制台中进行一些点击操作来完成的:

  1. 为 Cloud SQL 实例分配公共 IP(如果需要,可以将其视为 AWS 弹性 IP)。
  2. 允许你本地的 IP 地址/范围访问 Cloud SQL 实例。

更正 Django 设置

对于在 App Engine 上运行的生产实例:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '/cloudsql/project-name:instance-name',
        'NAME': 'name_of_pre_created_database',
        'USER': 'root_or_pre_created_user',
    }
}

用于连接到生产云SQL实例的开发实例:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '198.198.88.88', 
        'NAME': 'name_of_pre_created_database',
        'USER': 'root_or_pre_created_user',
        'PASSWORD': 'password_of_pre_created_or_root_user',
    }
}

在您请求Cloud SQL实例后(请参见上文),198.198.88.88是Google自动分配给您的IP地址。请记住,您需要从已允许访问该特定Cloud SQL实例的IP地址连接。

有了这个,google.appengine.ext.django.backends.rdbms可以退役了(松一口气)。


非常感谢,我已经苦苦挣扎了很久。不知道为什么AppEngine文档没有得到维护。 - Chakradar Raju
我只是为了点赞这篇帖子而登录。您真是太棒了,这正好符合需求。 - slumtrimpet
不用客气。我希望我能回答为什么它们没有得到维护;至少他们可以删除过时的破损文档。或者,开源这个项目吧! - Darian Moody
这很有帮助。顺便问一下,你是怎样让 Django 1.6 在 GAE 上运行的呢?你能否指点我如何在 Google App Engine 上让 Django 版本大于 1.5 的方法? - Sunny

3
连接开发应用服务器到Cloud SQL的推荐方法是请求一个实例的IP,然后将其作为普通的IP连接使用。具体操作请参考文档

1
这是正确的方法。我还需要授权我的本地网络地址,并确保实例上设置了根密码。根据此链接,原始的OAuth2身份验证方法现在已被弃用:https://developers.google.com/cloud-sql/docs/external。Django页面尚未反映出这一点。感谢您的帮助! - Charles Brandt

1
我很确定这是因为Django API已经更改,而App Engine SDK从未得到更新。我进行了一些调整,使其正常工作: https://gist.github.com/pizzapanther/fe8c29a912a109806bd8 主要更改如下:
  1. _valid_connection()现在是is_usable
  2. Connect(**kwargs)之后添加了self.set_autocommit(self.settings_dict['AUTOCOMMIT'])
可能还有更多适当的更改需要进行,但由于此驱动程序通常仅用于部署诸如迁移之类的事情,因此这样就可以了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接