英文:
Can't pass database URL to imdbpy2sql.py script
问题
无论我运行imdbpy2sql.py还是s32cinemagoer.py,都会出现相同的错误:
python3 s32cinemagoer.py /home/username/frozendata 'mysql://imdb:imdb@localhost/imdb'
Traceback (most recent call last):
File "s32cinemagoer.py", line 197, in <module>
engine = sqlalchemy.create_engine(db_uri, encoding='utf-8', echo=False)
File "<string>", line 2, in create_engine
File "/home/username/.local/lib/python3.8/site-packages/sqlalchemy/util/deprecations.py", line 281, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
File "/home/username/.local/lib/python3.8/site-packages/sqlalchemy/engine/create.py", line 680, in create_engine
raise TypeError(
TypeError: Invalid argument(s) 'encoding' sent to create_engine(), using configuration MySQLDialect_mysqldb/QueuePool/Engine. Please check that the keyword arguments are appropriate for this combination of component
我已经查看了SQLAlchemy文档中关于create_engine()函数的内容,但仍然不明白我传递的参数有什么问题。create_engine函数接受多个参数(例如engine = create_engine("mysql://scott:tiger@hostname/dbname", encoding='latin1', echo=True),包括"encoding"参数。
以下是SQLAlchemy文档关于MySQL中的传统utf-8编码的说明:
用于Unicode的编码传统上是'utf8'。然而,在MySQL版本5.5.3和MariaDB 5.5以后,引入了一个新的MySQL特定编码'utf8mb4',并且在MySQL 8.0版本中,如果在任何服务器端指令中指定了普通utf8,则服务器会发出警告,并将其替换为utf8mb3。这种新编码的原因是MySQL的传统utf-8编码只支持最多三个字节的代码点,而不是四个字节。因此,在与包含大于三个字节大小的代码点的MySQL或MariaDB数据库通信时,如果数据库和客户端DBAPI都支持此新字符集,则首选此字符集。
这是cinemagoer包中的set_connection()函数,可能传递了错误的编码:
def setConnection(uri, tables, encoding='utf8', debug=False):
"""Set connection for every table."""
params = {'encoding': encoding}
# FIXME: why on earth MySQL requires an additional parameter,
# is well beyond my understanding...
if uri.startswith('mysql'):
if '?' in uri:
uri += '&'
else:
uri += '?'
uri += 'charset=%s' % encoding
我现在尝试使用SQLAlchemy 1.3运行脚本,如这里建议的,以及PyMySQL适配器(否则会出现"No module named 'MySQLdb'"错误5),但似乎仍然不起作用,仍然出现相同的问题。
- Ubuntu 20.04.6 LTS
- Python 3.8.10
- cinemagoer 2023.5.1
- SQLAlchemy 1.3/2.0
英文:
Whether I'm running imdbpy2sql.py or s32cinemagoer.py the same error occurs:
python3 s32cinemagoer.py /home/username/frozendata 'mysql://imdb:imdb@localhost/imdb'
Traceback (most recent call last):
File "s32cinemagoer.py", line 197, in <module>
engine = sqlalchemy.create_engine(db_uri, encoding='utf-8', echo=False)
File "<string>", line 2, in create_engine
File "/home/username/.local/lib/python3.8/site-packages/sqlalchemy/util/deprecations.py", line 281, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
File "/home/username/.local/lib/python3.8/site-packages/sqlalchemy/engine/create.py", line 680, in create_engine
raise TypeError(
TypeError: Invalid argument(s) 'encoding' sent to create_engine(), using configuration MySQLDialect_mysqldb/QueuePool/Engine. Please check that the keyword arguments are appropriate for this combination of component
I've checked SQLAlchemy documentation on create_engine() function, but still don't get what's the issue with the argumetns I am passing in. create_engine function takes several arguments (e.g.engine = create_engine("mysql://scott:tiger@hostname/dbname", encoding='latin1', echo=True) including "encoding" argument.
Here is what SQLAlchemy documentation says about legacy utf-8 encoding in MySQL:
> The encoding used for Unicode has traditionally been 'utf8'. However,
> for MySQL versions 5.5.3 and MariaDB 5.5 on forward, a new
> MySQL-specific encoding 'utf8mb4' has been introduced, and as of MySQL
> 8.0 a warning is emitted by the server if plain utf8 is specified within any server-side directives, replaced with utf8mb3. The
> rationale for this new encoding is due to the fact that MySQL’s legacy
> utf-8 encoding only supports codepoints up to three bytes instead of
> four. Therefore, when communicating with a MySQL or MariaDB database
> that includes codepoints more than three bytes in size, this new
> charset is preferred, if supported by both the database as well as the
> client DBAPI.
Here is the set_connection() function from cinemagoer package that probably passes wrong encoding:
def setConnection(uri, tables, encoding='utf8', debug=False):
"""Set connection for every table."""
params = {'encoding': encoding}
# FIXME: why on earth MySQL requires an additional parameter,
# is well beyond my understanding...
if uri.startswith('mysql'):
if '?' in uri:
uri += '&'
else:
uri += '?'
uri += 'charset=%s' % encoding
I am now trying to run script with SQLAlchemy 1.3, as suggested here and PyMySQL adapter (otherwise I get No module named 'MySQLdb' error), but it doesn`t seem to work either, same issue occurs.
- Ubuntu 20.04.6 LTS
- Python 3.8.10
- cinemagoer 2023.5.1
- SQLAlchemy 1.3/2.0
答案1
得分: 0
需要将 -u 参数用引号括起来吗?
英文:
Do you need to wrap the -u argument in quotes?
答案2
得分: 0
def setConnection(uri, tables, encoding='utf8', debug=False):
"""为每个表设置连接。"""
# FIXME: 为什么 MySQL 需要额外的参数,超出了我的理解范围...
if uri.startswith('mysql'):
if '?' in uri:
uri += '&'
else:
uri += '?'
uri += 'charset=%s' % encoding
engine = sqlalchemy.create_engine(uri, echo=debug)
......
英文:
can you try this? just an example, passing encoding directly to db uri
def setConnection(uri, tables, encoding='utf8', debug=False):
"""Set connection for every table."""
# FIXME: why on earth MySQL requires an additional parameter,
# is well beyond my understanding...
if uri.startswith('mysql'):
if '?' in uri:
uri += '&'
else:
uri += '?'
uri += 'charset=%s' % encoding
engine = sqlalchemy.create_engine(uri, echo=debug)
......
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论