我在my setup.py file: create_tables
和drop_tables
有两个自定义命令:
class create_tables(command):
description = 'create DB tables'
user_options = [
('database=', 'd', 'which database configuration use'),
('reset', 'r', 'reset all data previously'),
]
def initialize_options(self):
command.initialize_options(self)
self.reset = False
def run(self):
if self.reset:
self.run_command('drop_tables')
else:
command.run(self)
from vk_relations import models
models.create_tables()
print 'Tables were created successfully'
class drop_tables(command):
description = 'drop all created DB tables'
user_options = [
('database=', 'd', 'which database configuration use'),
]
def run(self):
command.run(self)
answer = raw_input('Are you sure you want to clear all VK Relations data? (y/n): ')
if 'y' == answer:
from vk_relations import models
models.drop_tables()
print 'Tables were dropped successfully'
elif 'n' == answer:
quit()
else:
sys.exit()
命令$ setup.py create_tables -r -dmain
应运行命令drop_tables
并在main
数据库创建新表,但run_command
方法不允许为命令提供选项。如何在database
命令中为drop_tables
指定选项create_tables
?
答案 0 :(得分:1)
现在我用过这个黑客:
cmd_obj = self.distribution.get_command_obj('drop_tables')
cmd_obj.database = self.database
self.run_command('drop_tables')
答案 1 :(得分:1)
对于诸如build
之类的预定义目标,在对象上设置属性将失败。
您可以在这里找到最合适的解决方案的最接近的是:
class drop_tables(command): # <-- Note this should come from drop_tables command
def finalize_options(self):
self.set_undefined_options("create_tables", ("database", "database"))
这是一种用于将参数从build
继承到build_py
和其他子命令的方法。
build
命令我不喜欢build命令中引入的distutils
包的作者的循环引用。
执行顺序如下:build
命令调用build_py
子命令。子命令返回到build
命令,并获取未定义的参数。这使得紧密耦合,因为两个命令都需要彼此了解。
同样,如果要添加另一个聚合命令,则会引入歧义-build_py
将具有两个要继承的参数源。
减少耦合的方法应该有所不同。
如果build
命令是一个聚合命令,因此它应该处理传递给其子命令的所有参数。
class build(command):
...
def finalize_options(self):
for cmd_name in self.get_sub_commands():
cmd_obj = self.distribution.get_command_obj(cmd_name)
cmd_obj.set_undefined_options("build", ("build_lib", "build_lib"), ...)
现在,无需按名称传递命令,我们可以使用instance代替。这还将解决set_undefined_options
> ensure_finalized
> finalize_options
> set_undefined_options
鉴于当前的状况,针对您的问题的更好解决方案是:
class create_tables(command):
def run(self):
cmd_obj = self.distribution.get_command_obj("drop_tables")
cmd_obj.set_undefined_options("create_tables", ("database", "database"))
self.run_command("drop_tables")