我正在用Python编写数据库迁移脚本,我在其中创建了一个可以在版本之间迁移数据库的字典。我目前这样做如下:
def from1To2():
pass # migration script here
def from2To1():
pass # migration script here
# etc
migrations = {
1: {'up': from1To2},
2: {'down': from2To1, 'up': from2To3},
3: {'down': from3To2, 'up': from3To4},
4: {'down': from4To3},
}
但是每次创建新的迁移时,我都需要编写两个迁移脚本(向上和向下)并将它们放在迁移字典中。由于迁移功能非常小(通常是两行),我想在迁移字典中直接写它们。在Javascript中,这看起来像:
migrations = {
1: {
'up': function(){ addSomeColumn(); recordChange(); },
'down': function(){ dropSomeColumn(); recordChange(); }
},
2: etc
}
因为迁移功能通常是两行,所以我认为我不能使用lambda函数。有没有人知道在Python中用dict直接编写函数的其他方法?欢迎所有提示!
答案 0 :(得分:6)
写一个自定义装饰器:
migrations = {}
def migrate(old_version, new_version):
assert abs(new_version-old_version)==1
def decorator(f):
direction = 'up' if new_version > old_version else 'down'
if old_version not in migrations:
migrations[old_version] = {}
migrations[old_version][direction] = f
return f
return decorator
@migrate(1, 2)
def upgrade():
pass # migration script here
@migrate(2, 1)
def downgrade():
pass # migration script here
@migrate(2, 3)
def upgrade():
pass # migration script here
# etc
print(migrations)
输出类似于:
{1: {'up': <function upgrade at 0x02BE4588>}, 2: {'down': <function downgrade at 0x02BE4618>, 'up': <function upgrade at 0x02BE4540>}}
装饰负责更新migrations
字典,但这样函数可以有任何名称或重复使用相同的名称,或者可以在其他模块中(例如,有一个文件用于版本1到2并回滚和另一个2到3和回滚)。
答案 1 :(得分:0)
为此你需要使用lambda:
>>> function_dictionary = {'capitalize': lambda text: text.capitalize()}
>>> function_dictionary['capitalize']('word')
'Word'
答案 2 :(得分:0)
如果您的功能将返回True
,则可以使用{{1}}。