SQLAlchemy——我可以在 DDL 中将空字符串映射到 null 吗?我想要一个可为 null 的整数列在插入或更新时将 '' 转换为 NULL
SQLAlchemy--can I map an empty string to null in the DDL? I want a nullable integer column to translate '' to NULL on insert or update
我有一个 SQLAlchemy 模型,其中一个整数列是从 HTML 表单填充的(我正在使用 Flask 和 WTForms-alchemy,我试图避免在路由中编写自定义代码)。如果用户没有在表单上为这个整数输入值,从表单填充对象的代码最终会尝试为该列放入一个空字符串,并且 MySQL 会抱怨这不是一个整数值。帮助人们搜索:我从 Incorrect integer value: '' for column ...
.
开始的错误
我不想使用 sql_mode=''
hack,人们建议这样做是为了让 MySQL 回到每当你给它不正确的数据时进行猜测的旧行为,因为我无法控制最终将用于的 MySQL 服务器。
我想要的是类似于默认列规范的东西,只是我不想在没有传入任何内容时指定默认值,而是想拦截尝试放入空字符串并将其替换为 None 我认为它在进入数据库时会被转换为 null。
有没有办法在模型定义中做到这一点?我意识到这可能会导致性能下降,但吞吐量在此应用程序中并不是什么大问题。
我找到了一个方法。 validates
装饰器可以在进入的过程中改变一个值。我是这样做的:
from sqlalchemy.orm import validates
class Task(Base):
__tablename__ = 'task'
id = Column(INTEGER(11), primary_key=True)
time_per_unit = Column(INTEGER(11))
@validates('time_per_unit')
def empty_string_to_null(self, key, value):
if isinstance(value,str) and value == '':
return None
else:
return value
我 运行 遇到了类似的问题并创建了一个装饰器,然后可以在该字段的 setter 上使用它。这允许轻松重用,但确实需要为该字段使用混合 属性 和 setter。
helpers.py
def noneIfEmptyString(func):
@functools.wraps(func)
def wrapped_function(*args, **kwargs):
"""Decorator to convert empty string to None """
for arg in args:
if arg == '':
arg = None
for k,v in kwargs.items():
if v == '':
kwargs[k] = None
return func(*args, **kwargs)
return wrapped_function
Models.py
_columnName = db.Column(db.String(120))
@hybrid_property
def columnName(self):
return self._columnName
@columnName.setter
@noneIfEmptyString
def columnName(self, name):
self._columnName = name;
我有一个 SQLAlchemy 模型,其中一个整数列是从 HTML 表单填充的(我正在使用 Flask 和 WTForms-alchemy,我试图避免在路由中编写自定义代码)。如果用户没有在表单上为这个整数输入值,从表单填充对象的代码最终会尝试为该列放入一个空字符串,并且 MySQL 会抱怨这不是一个整数值。帮助人们搜索:我从 Incorrect integer value: '' for column ...
.
我不想使用 sql_mode=''
hack,人们建议这样做是为了让 MySQL 回到每当你给它不正确的数据时进行猜测的旧行为,因为我无法控制最终将用于的 MySQL 服务器。
我想要的是类似于默认列规范的东西,只是我不想在没有传入任何内容时指定默认值,而是想拦截尝试放入空字符串并将其替换为 None 我认为它在进入数据库时会被转换为 null。
有没有办法在模型定义中做到这一点?我意识到这可能会导致性能下降,但吞吐量在此应用程序中并不是什么大问题。
我找到了一个方法。 validates
装饰器可以在进入的过程中改变一个值。我是这样做的:
from sqlalchemy.orm import validates
class Task(Base):
__tablename__ = 'task'
id = Column(INTEGER(11), primary_key=True)
time_per_unit = Column(INTEGER(11))
@validates('time_per_unit')
def empty_string_to_null(self, key, value):
if isinstance(value,str) and value == '':
return None
else:
return value
我 运行 遇到了类似的问题并创建了一个装饰器,然后可以在该字段的 setter 上使用它。这允许轻松重用,但确实需要为该字段使用混合 属性 和 setter。
helpers.py
def noneIfEmptyString(func):
@functools.wraps(func)
def wrapped_function(*args, **kwargs):
"""Decorator to convert empty string to None """
for arg in args:
if arg == '':
arg = None
for k,v in kwargs.items():
if v == '':
kwargs[k] = None
return func(*args, **kwargs)
return wrapped_function
Models.py
_columnName = db.Column(db.String(120))
@hybrid_property
def columnName(self):
return self._columnName
@columnName.setter
@noneIfEmptyString
def columnName(self, name):
self._columnName = name;