【问题标题】:How to pass information about user and password to the command 'flask db migrate'如何将有关用户和密码的信息传递给命令“flask db migrate”
【发布时间】:2019-02-24 14:51:43
【问题描述】:

我正在关注在线 Flask 教程,但在您进行第一次数据库迁移时遇到了困难。在命令中

$ flask db migrate

我收到错误消息

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError)
(1045, "Access denied for user 'counter_app'@'localhost' (using password: NO)") 
(Background on this error at: http://sqlalche.me/e/e3q8)

不幸的是,错误消息中的链接没有提供足够的帮助,但我很确定我知道问题所在。使用该命令,我试图在不使用密码的情况下连接到数据库(“使用密码:否”),但是,对于有问题的用户“counter_app”,在 .flaskenv 文件中设置了一个密码,如下所示:

FLASK_APP='manage.py'
FLASK_ENV=development
SECRET_KEY='my_secret_key'
DB_HOST=localhost
DB_USERNAME='counter_app'
DB_PASSWORD='mypassword'
DATABASE_NAME='counter'

文件 appklication.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

# setup db
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)

    # Load config
    app.config.from_pyfile('settings.py')

    # initialize db
    db.init_app(app)
    migrate = Migrate(app, db)

    # import blueprints
    from counter.views import counter_app

    # register blueprints
    app.register_blueprint(counter_app)

    return app

然后通过 app.config.from_pyfile('settings.py'); 加载settings.py 看起来像这样:

import os

SECRET_KEY = os.getenv('SECRET_KEY')
DB_USERNAME=os.environ['DB_USERNAME']
DB_PASSWORD=os.environ['DB_PASSWORD']
DB_HOST=os.environ['DB_HOST']
DATABASE_NAME=os.environ['DATABASE_NAME']
DB_URI = 'mysql+pymysql://%s:%s@%s:3306/%s' % (DB_USERNAME, DB_PASSWORD, DB_HOST, DATABASE_NAME)
SQLALCHEMY_DATABASE_URI = DB_URI

如果这工作正常,这个序列应该设置 DB_USERNAME,它会这样做,但它也应该设置 DB_PASSWORD,它不会。所以问题似乎是烧瓶命令没有得到它应该读取 .flaskenv 文件中的信息,然后在迁移数据库时使用密码。发出命令时,我与 .flaskenv 文件位于同一目录中。另外,我可以手动登录数据库,所以我知道 .flaskenv 文件中的用户名和密码是正确的。

关于命令行选项的文档烧瓶非常简洁,没有给出如何指定数据库用户和密码的任何示例。那么如何强制“flask db migrate”命令使用正确的用户名和密码呢?

【问题讨论】:

标签: python mysql flask


【解决方案1】:

我是课程的作者。出现的问题是 Homebrew 上 MySQL 的最新软件包已更新为安装 MySQL 8.0。本课程假设您正在安装 MySQL 5.7,这是一个月前的默认 Homebrew 软件包。

要解决此问题,请在本地系统中安装特定版本的 MySQL。

如果您已经安装,请先卸载,使用brew remove mysql。

然后,使用brew install mysql@5.7 安装。

问题在于 MySQL 8.0+ 有一种新的身份验证机制,可以自动加密密码。

如果您仍想使用 MySQL 8.0,您可以通过执行以下操作更改 counter_app 用户以使用密码:

ALTER USER 'counter_app'@'%' IDENTIFIED WITH mysql_native_password BY 'mypassword';

或者,如果您想从头开始创建它,请执行以下操作:

CREATE USER 'counter_app'@'%' IDENTIFIED WITH mysql_native_password BY 'mypassword';

【讨论】:

  • 感谢您的回答(一个很棒的课程)。从头开始重做一切,包括删除然后重新安装mysql。我从 repo 中复制了文件,据我所知,.flaskenv 和 settings.py 是相同的(请参阅github.com/niklasrudemo/visitor-counter)。添加import pdb; pdb.set_trace() 会产生:(Pdb) current_app.config['DB_USERNAME'] 'counter_app' (Pdb) current_app.config['DB_PASSWORD'] 'mypassword'。然而flask db migrate 仍然以同样的方式失败。
【解决方案2】:

要使用.env 和.flaskenv 配置点文件,您需要安装和配置python-dotenv。

python-dotenv: Getting Started

flask: Environmental Variables from dotenv

我见过的大多数项目都没有单独的.flaskenv,而是有一个包含所有应用程序机密的.env 文件,该文件不受版本控制。

【讨论】:

  • 使用 python-dotenv 似乎是一件好事,但这不是本教程使用的,它设法读取数据库的用户名,因此这部分工作原理上。问题似乎是它没有从 .flaskenv 文件中读取密码,或者它不明白它应该在迁移时使用它
  • 在“从零到烧瓶”课程中,“Say Hello World”的最后一课标题为“Python Dot Env for PythonAnywhere”。描述中提到将python-dotenv 添加到requirements.txt 文件中。一旦你这样做了,你需要运行pip install -r requirements.txt。
  • 你说得对,Richard,这个例子确实已经使用了python-dotenv==0.8.2。我尝试在解释器中逐行运行 application.py,当我到达 app.config.from_pyfile('settings.py') 时,我收到此错误:KeyError: 'DB_USERNAME'。所以好像读取settings.py中的环境变量不能正常工作。
猜你喜欢
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 2017-01-04
  • 2012-09-21
  • 2020-02-15
相关资源
最近更新 更多