当我尝试在MongoEngine中保存DynamicDocument时,我正在尝试调试奇怪的行为。 文档类声明如下:
class Command(DynamicDocument):
meta = {
'collection': 'executor_data_commands'
}
name = StringField()
args = DynamicField()
issued_at = LongField(default=time.time())
sync_with_kafka = BooleanField(default=False)
correlation_id = StringField(
default=''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))
)
commands_output = DynamicField(default=None)
@classmethod
def post_save(cls, sender, document, **kwargs):
"""
Send data to Kafka executor data topic after a new instance has been saved
:param sender: the sender who emitted the signal
:param document: the saved instance
"""
if kwargs['created']:
CommandHandler(document).send_command()
class CommandHandler:
"""
Command handler class
"""
def __init__(self, command_instance):
self.command_instance = command_instance
def send_command(self):
"""
Send command to Kafka queue and save the response in the
local database
:return: True if message is published over Kafka channel
False otherwise
"""
headers = {
"Content-Type": "application/vnd.kafka.json.v2+json",
"Accept": "application/vnd.kafka.v2+json"
}
logger_kafka_handlers.info(
"Got new command: %s - %s" % (self.command_instance.name, self.command_instance.args))
args = self.command_instance.args
if 'machine_identifier' in args:
args['machine_identifier'] = MACHINE_MAPPING.get(args['machine_identifier'], args['machine_identifier'])
response = requests.post(
KAFKA_BROKER_EXECUTOR_COMMANDS_IN['host'],
json={"records": [{"value": {
"name": self.command_instance.name,
"args": args,
"correlation_id": self.command_instance.correlation_id,
"issued_ts": time.time()
}}]},
headers=headers,
auth=(KAFKA_BROKER_EXECUTOR_COMMANDS_IN['user'], KAFKA_BROKER_EXECUTOR_COMMANDS_IN['password'])
)
self.command_instance.sync_with_kafka = True if response.status_code == 200 else False
self.command_instance.save()
logger_kafka_handlers.info(
"Handled new command; Name: %s - Args: %s - Sync with Kafka: %s; CorrelationId: %s" % (
self.command_instance.name, self.command_instance.args, self.command_instance.sync_with_kafka,
self.command_instance.correlation_id))
因此,我希望创建的文档具有10个字母的随机 correlation_id ,并传递给 post_save 处理程序,该处理程序基本上执行HTTP请求并记录实例字段。>
问题与 correlation_id 字段相关: 似乎分配给每个已保存实例的默认值等于数据库中保存的另一个值。
由于排除了在 send_command 方法的最后一行中记录实例字段时出现的问题,因此我不公开进行内部更新查询以及进行一些变量重新分配。
想法?
谢谢, FB
答案 0 :(得分:1)
问题在于您对default
的理解。
我不确定mongo DynamicDocument,但我认为它的行为与普通模型相同。
所以, 从文档中:
该字段的默认值。这可以是值或可调用 宾语。如果可调用,则每次有新对象时都会调用它 已创建。
对于您而言,它是不可调用的,因此在创建模型类时仅调用一次。
您需要使其可调用,因此请将实现变为函数:
def generate_random_corr():
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))
并在模型类中使用它,如下所示:
correlation_id = StringField(default=generate_random_corr)
其他字段同样适用:
issued_at = LongField(default=time.time())
所有对象的时间都相同。