从 mysqlclient 更改为 pymysql 的问题:将 dict 另存为字符串

Problem with changing from mysqlclient to pymysql: save dict as string

由于许可证问题,我需要将当前使用库 mysqlclient 的项目更改为使用 pymysql。

该项目使用了sqlalchemy,没有直接使用mysqlclient,所以我以为我只需要更改连接字符串,但我似乎遇到了一个边缘情况。

我在代码中有一些地方在 sqlalchemy 模型中将某些列定义为字符串,但出于某种原因(旧代码),代码试图将字典放在那里。这通过将 dict 转换为 str 来实现(这是所有类型的预期行为 - 如果我输入 int 它将被转换为 str)。

当我从库 mysqlclient 更改为 pymysql 时,此行为似乎会中断 听写。

下面是复制此问题的示例代码:

import sqlalchemy
from sqlalchemy import Column, Integer, String, DateTime, func, text, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker


SCHEMA = 'testing'
con = "mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}/{SCHEMA}?charset=utf8mb4".format(USERNAME='reducted',
                                                                                     PASSWORD="reducted",
                                                                                     HOST='127.0.0.1:3306',
                                                                                     SCHEMA=SCHEMA)
engine = sqlalchemy.create_engine(con, pool_recycle=3600, pool_size=20, pool_pre_ping=True, max_overflow=100)
metadata = MetaData(bind=engine)
base = declarative_base(metadata=metadata)

class TestModel(base):
    __tablename__ = 'test_table'
    __table_args__ = {'autoload': False,
                      'schema': SCHEMA
                      }
    id = Column(Integer(), primary_key=True, nullable=False, index=True)
    test_value = Column(String(50), nullable=False)
    date_created = Column(DateTime, server_default=func.now(), index=True)
    date_modified = Column(DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), index=True)

metadata.create_all()

session_maker = sessionmaker(bind=engine)
session = session_maker()
row = TestModel()
row.test_value = {}
session.add(row)
session.commit()

这会导致此错误You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '})' at line 1

如果将连接字符串中的 pymysql 更改为 mysqldb,代码将起作用。

我的问题是: 是否有解决方法或是否有 sqlalchemy 挂钩我可以自己使用 cast the dicts?

此外,如果我知道从 mysqlclient 迁移到 pymysql 的更多问题,我将不胜感激任何提示,我似乎找不到任何差异的文档(许可证部分除外)

is there a sqlalchemy hook i can use cast the dicts myself?

您可以将 validator 添加到您的 TestModel class:

    @validates("test_value")
    def validate_test_value(self, key, thing):
        if isinstance(thing, dict):
            return str(thing)
        else:
            return thing