Flask 和 Heroku sqlalchemy.exc.NoSuchModuleError: 无法加载插件: sqlalchemy.dialects:postgres。

17
当我运行时
heroku run python
>>> from app.main import app
>>> app.config['SQLALCHEMY_DATABASE_URI']
'postgres://<url string>' # the database url is passed correctly
>>> from app.main import db
>>> db.create_all()

出现了以下错误:

  Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1039, in create_all
    self._execute_for_all_tables(app, bind, 'create_all')
  File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1031, in _execute_for_all_tables
    op(bind=self.get_engine(app, bind), **extra)
  File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 962, in get_engine
    return connector.get_engine()
  File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 556, in get_engine
    self._engine = rv = self._sa.create_engine(sa_url, options)
  File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 972, in create_engine
    return sqlalchemy.create_engine(sa_url, **engine_opts)
  File "<string>", line 2, in create_engine
  File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/util/deprecations.py", line 298, in warned
    return fn(*args, **kwargs)
  File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/create.py", line 520, in create_engine
    entrypoint = u._get_entrypoint()
  File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/url.py", line 653, in _get_entrypoint
    cls = registry.load(name)
  File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 342, in load
    "Can't load plugin: %s:%s" % (self.group, name)
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres

我感到困惑,因为我是Heroku和Postgresql的新手(一直使用SQLite),而我所遵循的教程都没有解释它们如何与Flask连接,只是告诉我该怎么做。因此,我不知道要查看什么来解决问题。是否还有其他代码需要包含在问题中?
(大多数类似这个的问题都是拼写错误或无法解决此问题的错误。)

你能否添加你的代码,或者至少提供一个最小可重现示例(https://stackoverflow.com/help/minimal-reproducible-example)? - Rivers
3个回答

23

这是由于sqlalchemy库的更改所致。在SQLALCHEMY_DATABASE_URI(冒号前的部分)名称中,宣布将dialect(方言)名称postgres更改为postgresql。他们通过GitHub提交记录次要版本发布实施了这个破坏性更改,这是他们的政策。

Heroku默认提供的DATABASE_URL的方言是postgres,会被转换成SQLALCHEMY_DATABASE_URI。如果更新不会破坏可能依赖于它的其他库,则Heroku可以更新其postgres插件。

在此期间,您可以将您的sqlalchemy库降级回<1.4.0(1.3.23是最后一个1.3.x版本),然后它应该可以正常工作。

或者,您可以更新您的代码以修改方言。


21

这是一个对我有效的快速方法,适用于最新的Heroku上的PostgreSQL:

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL').replace("://", "ql://", 1)

只需从Heroku的postgres://中入手(该部分无法编辑),将其改为postgresql://


4
如果Heroku更新了环境变量的值,可能需要进行完整的SQLALCHEMY_DATABASE_URI更新:SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL').replace("postgres://", "postgresql://", 1)这样可以确保代码继续正常运行。 - melinath

0

我正在使用SQLAlchemy ORM项目将我的快速API推送到Heroku,使用PostgreSQL+asyncpg,也遇到了这个问题,我使用以下方法解决了它:

def change_postgres_connection_string(connection_string):
    if connection_string.startswith('postgresql+asyncpg://'):
        return connection_string
    parts = connection_string.split(':')
    parts[0] = 'postgresql+asyncpg'
    return ':'.join(parts)

你的回答需要更多的支持性信息。请编辑以添加进一步的细节,例如引用或文档,以便其他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - moken

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