python - Flask SqlAlchemy/Alembic 迁移将无效字符集发送到 PyMysql
问题描述
在过去的 21 天中,有 18 天我为此花费了 3 多个小时。请有人告诉我我的误解是什么!
TL;DR:我的代码反复将 db 字符集作为字符串发送到 PyMysql,而它需要一个具有名为“encoding”的属性的对象
背景
这是在 docker 容器上运行的 Python 代码。第二个容器容纳数据库。数据库地址存储在一个.env
名为的变量中ENGINE_URL
:
ENGINE_URL=mysql+pymysql://root:@database/starfinder_development?charset=utf8
我正在使用click
CLI 中的命令启动 Alembic 和 Flask-Alembic 命令。以下所有方法都在 CLI 命令中使用。
模型/数据库设置(作品)
from flask import Flask
flask_app = Flask(__name__)
db_engine = SQLAlchemy(flask_app)
from my_application import models
def create_database():
db_engine.create_all()
此时我可以打开数据库容器并使用 MySql CLI 看到我的所有模型现在都已转换为具有列和关系的表。
尝试 1:Alembic
使用 Alembic 创建修订文件(作品)
from alembic.config import Config
def main(): # fires prior to any CLI command
filepath = os.path.join(os.path.dirname(__file__),
"alembic.ini")
alembic_config = Config(file_=filepath)
alembic_config.set_main_option("sqlalchemy.url",
ENGINE_URL)
alembic_config.set_main_option("script_location",
SCRIPT_LOCATION)
migrate_cli(obj={"alembic_config": alembic_config})
def revision(ctx, message):
alembic_config = ctx.obj["alembic_config"]
alembic_command.revision(alembic_config, message)
此时我有一个迁移文件,它完全按照预期创建。然后我需要使用该迁移升级数据库......
使用 Alembic 运行迁移(失败)
def upgrade(ctx, migration_revision):
alembic_config = ctx.obj["alembic_config"]
migration_revision = migration_revision.lower()
_dispatch_alembic_cmd(alembic_config, "upgrade",
revision=migration_revision)
触发它cli_command upgrade head
会导致失败,我将其包含在底部,因为它与我的第二次尝试具有相同的堆栈跟踪。
尝试 2:Flask-Alembic
这次尝试发现我完全重写了我的main
和revision
命令,但它并没有达到使用upgrade
.
使用 Flask-Alembic 创建修订文件(失败)
def main(): # fires prior to any CLI command
alembic_config = Alembic()
alembic_config.init_app(flask_app)
migrate_cli(obj={"alembic_config": alembic_config})
def revision(ctx, message):
with flask_app.app_context():
alembic_config = ctx.obj["alembic_config"]
print(alembic_config.revision(message))
这会导致与我之前尝试的错误相同的错误。
两种情况下的堆栈跟踪:
(使用蒸馏器升级和烧瓶蒸馏器修订相同的失败)
File "/Users/MyUser/.pyenv/versions/3.6.2/envs/sf/lib/python3.6/site-packages/pymysql/connections.py", line 678, in __init__
self.encoding = charset_by_name(self.charset).encoding
AttributeError: 'NoneType' object has no attribute 'encoding'
作为回应,我进入了上述文件并L677
在错误之前添加了一个 print on :
打印(self.charset)
utf8
注意:如果我修改 myENGINE_URL
以使用不同的?charset=xxx
,则该更改会在此处反映出来。
所以现在我很难过
PyMysql 期望self.charset
有一个属性encoding
,但self.charset
它只是一个字符串。我怎样才能改变它以达到预期的效果?
帮助?
一个有效的答案将是一个替代过程,尽管“最正确”的答案是帮助我解决字符集/编码问题。
我的主要目标只是让迁移在我的烧瓶应用程序上运行。
解决方案
推荐阅读
- shell - 来自php节点js的Webusb adb shell可以通过网站与手机等USB设备进行通信
- python - 如何使用 python 实现客户端到启用 grpc-inflection 的服务器?
- flutter - Flutter:AppBar 中的旋转同步图标
- image - 将所有 RGB 颜色生成为图像
- processing - 使用处理的反向步态分析
- java - 在 Spinner Android Studio 中遇到问题
- python - 如何使矩形通过 pygame 移动?我的代码似乎不起作用
- c++ - 在 Opengl 和 SDL2 应用程序中打开 VSYNC 的高 CPU 使用率
- sql - 如何创建包含多个字段的唯一索引,其中一个是外键
- video - 使用mpeg2video的FFmpeg黑屏