我有一个包含3行的表格,如下所示:
| serverID | behavior | limit |
---------------------------------
| 102 | action1 | 5 |
| 103 | action2 | 8 |
我在这里有此功能:
def set_warn_settings(serverID, behavior, limit):
with INSERTION_LOCK:
try:
row = SESSION.query(WarnSettings).filter(WarnSettings.serverID == serverID).first()
if row:
row.behavior = behavior
row.limit = limit
SESSION.add(row)
SESSION.commit()
else:
action = WarnSettings(serverID, behavior, limit)
SESSION.add(action)
SESSION.commit()
finally:
SESSION.close()
当我调用该函数且参数之一为None
时,该列的值将替换为None
,而不是像以前那样保留它。有时仅使用其中一个参数除None
以外的参数来调用该函数。
如何通过一个功能来更新某一列的值,而其余部分保持不变?
答案 0 :(得分:0)
所以这取决于您的要求...但是在设置之前,您应该检查behavior
和limit
的值:
if behavior is not None:
row.behavior = behavior
if limit is not None:
row.limit = limit
但是,您可能会认为有些时候您希望能够将这些字段设置为None
。在这种情况下,您可以默认将参数设置为特定对象。示例:
no_value = object()
def set_warn_settings(serverID, behavior=no_value, limit=no_value):
...
if behavior is not no_value:
row.behavior = behavior
if limit is not no_value:
row.limit = limit
...
答案 1 :(得分:0)
处理此问题的一种方法是在函数签名中使用**kwargs
构造。然后,在调用函数时不要使用位置参数,而仅使用要更新的属性的关键字参数来调用它:
def set_warn_settings(serverID, **kwargs):
with INSERTION_LOCK:
try:
row = SESSION.query(WarnSettings).get(serverID)
if row:
for k, v in kwargs.items():
setattr(row, k, v)
# i removed SESSION.add(row) from here as you don't need to
# re-add an instance that was retrieved via Session.query.
SESSION.commit()
else:
action = WarnSettings(**kwargs)
SESSION.add(action)
SESSION.commit()
finally:
SESSION.close()
如果行存在,这只会更新作为关键字参数传递给函数的属性名称的值,如果行尚未存在,将使用传递的值创建一个新的WarnSettings
实例存在。它也不会覆盖您不想设置为None
的属性的值,但是如果需要,还可以允许您将值显式设置为None
。
根据示例数据使用示例:
set_warn_settings(102, behavior='action2') # will change value of 'behavior' and not change 'limit'.
set_warn_settings(103, behavior='action1', limit=10) # will change both fields
set_warn_settings(104, behavior='action3', limit=3) # will create a new instance
请注意,我还在函数中使用了.get()
方法,这是一种通过主键查询并在行不存在时返回None
的巧妙方法。