使用flask_sqlalchemy给出以下模型:
class Student(DB.Model):
"""A student."""
id_: DB.Mapped[uuid.UUID] = DB.mapped_column(
primary_key=True, default=uuid.uuid4
)
first_name: DB.Mapped[str] = DB.mapped_column(StrippedString(16))
last_name: DB.Mapped[str] = DB.mapped_column(StrippedString(32))
full_name: DB.Mapped[str] = DB.column_property(
first_name + " " + last_name,
)
每次打印
full_name
时,中间都不存在空格。我认为这是因为 first_name
是 StrippedString
类型:
class StrippedString(TypeDecorator):
"""An augmented string type.
It strips whitespace upon the binding of the value as a parameter to a
query.
"""
impl = DB.String
cache_ok = True
def process_bind_param(self, value, dialect):
"""Strip the value (if it exists) from leading and trailing whitespace."""
return value.strip() if value else None
上面的
process_bind_param
函数也应用于 " "
,导致 first_name
和 last_name
之间没有空格。
如果我将
first_name
的列类型更改为DB.String(16)
,一切都很好。当然,除了我想为 StrippedString
保留 first_name
类型。
所以,现在我的问题是:如何设置(或影响)纯字符串
" "
的类型?基本上,我希望硬编码的 " "
保持不变,而不是被视为另一个 StrippedString
。
根据@python_user 对问题的评论,解决方案相当简单:
full_name: DB.Mapped[str] = DB.column_property(cast(first_name, DB.String) + " " + last_name)
就可以了。
我相信正在发生的是 SQLAlchemy 正在尝试对连接元素的类型进行智能处理。在我原来的问题中,第一个是
StrippedString
,它将相同的类型应用于第二个(文字 " "
),这当然会导致空字符串。
在这个新场景中,第一种类型是
String
,因此这适用于第二种类型,保持名字和姓氏之间的硬编码空格。
问题解决了!