SQLAlchemy 上下文敏感函数用于插入和更新时创建复合值

4 投票
2 回答
1091 浏览
提问于 2025-04-16 03:45

我正在尝试弄清楚如何添加一个上下文敏感的功能(比如 def get_user_full_name()),这个功能会在默认值和更新时被触发。我想设置一个组合字段,把名字和姓氏合并成一个完整的名字,这样就不用在所有查询中不断地拼接这两个字段了。

我使用的是声明式方法。这是一个类似模型的例子:

class SomeMembers(Base):
    __tablename__ = 'some_members'
    __table_args__ = {'mysql_engine':'InnoDB'}

    SomeGroup = Column(Unicode(50), primary_key=True)
    UserID = Column(Unicode(50), primary_key=True)
    FullName = Column(Unicode(255), default=get_user_full_name, onupdate=get_user_full_name, index=True)
    FirstName = Column(Unicode(255), index=True)
    LastName = Column(Unicode(255), index=True)
    UserName = Column(Unicode(255))

这是我写的一个函数,它在堆栈跟踪中报告说 FirstName 或 LastName 的键都不合法:

def get_user_full_name(context):
    return " ".join((context.compiled_parameters[0]['FirstName'],context.compiled_parameters[0]['LastName']))

我不太清楚如何引用这两个列(FirstName 和 LastName)已有的数据,以创建一个组合值,方便以后取用。比如,如果我有一个用户叫 John Doe,那么 get_user_full_name 方法应该把 "John" 和 "Doe" 结合起来,返回一个完整的名字 "John Doe"。

文档中提到 context.current_parameters,但在我的情况下并不存在。我怀疑这是因为我们使用了声明式方法。如果它能工作,我的 get_user_full_name 函数应该像这样:

def get_user_full_name(context):
    return " ".join((context.current_parameters['FirstName'],context.current_parameters['LastName']))

我知道这可能是个小问题,但我就是搞不清楚这些信息存在哪里,以及如何动态访问它。

如果能提供一些见解,我会非常感激。我也愿意尝试更优雅的方法。

提前谢谢你...

祝好,

保罗

2 个回答

0

我尝试了以下表达式:

from sqlalchemy.sql.expression import column, literal, literal_column

Column('full_name', String, onupdate=literal_column("first_name") + literal(" ") + literal_column("last_name"))

这个方法有点效果,但它把full_name更新成了之前的first_namelast_name的值。使用column也得到了同样的结果。

使用一个复合列能解决这个问题吗?

2

如果有人在找答案的话,这里有个提示。

你可以使用 映射器事件

@event.listens_for(SomeMembers, 'before_insert')
def before_insert_function(mapper, connection, target):
        target.FullName = f"{target.FirstName} {target.LastName}"

撰写回答