从 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
由于许可证问题,我需要将当前使用库 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