Различие правил безопасности Firebase между get () и getAfter ()

Уже есть много ответов, которые расскажут вам, как сделать правильную копию, но никто из них не говорит, почему ваша оригинальная «копия» не удалась.

Python не сохраняет значения в переменных; он связывает имена с объектами. Ваше исходное назначение взяло объект, на который ссылается my_list, и связал его с new_list. Независимо от того, какое имя вы используете, остается только один список, поэтому изменения, сделанные при обращении к нему как my_list, будут сохраняться при обращении к нему как new_list. Каждый из других ответов на этот вопрос дает вам различные способы создания нового объекта для привязки к new_list.

Каждый элемент списка действует как имя, поскольку каждый элемент связывается не исключительно с объектом. Неглубокая копия создает новый список, элементы которого привязываются к тем же объектам, что и раньше.

new_list = list(my_list)  # or my_list[:], but I prefer this syntax
# is simply a shorter way of:
new_list = [element for element in my_list]

Чтобы сделать копию списка еще на один шаг, скопируйте каждый объект, на который ссылается ваш список, и привяжите эти копии элементов в новый список.

import copy  
# each element must have __copy__ defined for this...
new_list = [copy.copy(element) for element in my_list]

Это еще не глубокая копия, потому что каждый элемент списка может ссылаться на другие объекты, точно так же, как список привязан к его элементам. Чтобы рекурсивно скопировать каждый элемент в списке, а затем каждый другой объект, на который ссылаются каждый элемент, и т. Д .: выполните глубокую копию.

import copy
# each element must have __deepcopy__ defined for this...
new_list = copy.deepcopy(my_list)

Для получения дополнительной информации о копировании в окне [gg] см. документацию .

0
задан Doug Stevenson 24 March 2019 в 02:34
поделиться

1 ответ

Во-первых, имейте в виду, что правила безопасности для записей вступают в силу до того, как что-либо в базе данных было изменено этой записью. Таким образом, правила безопасности могут безопасно и эффективно отклонять доступ без необходимости откатывать любые записи, которые уже произошли.

Документация, на которую вы ссылаетесь, предполагает, что getAfter полезен для проверки содержимого базы данных после того, как будет записано состояние всей транзакции (в некой «промежуточной» среде в памяти), но [ 1116] до того, как транзакция фактически изменит базу данных , видимую каждому. Это отличается от get, потому что get просматривает только фактическое содержимое базы данных, , прежде чем транзакция будет окончательно зафиксирована . Короче говоря, getAfter использует всю поэтапную запись всей транзакции или пакета, в то время как get использует фактическое существующее содержимое базы данных.

Вы ни в коем случае не обязаны использовать getAfter, если get отлично работает для вашего случая.

getAfter полезно, когда вам нужно проверить другие документы, которые могли быть изменены в транзакции или пакете, и при этом все еще есть возможность отклонить всю транзакцию или пакет, если не выполнить правило. Так, например, если два документа, которые пишутся в одной транзакции, должны иметь какое-то общее значение поля, чтобы быть согласованными, вам нужно использовать getAfter для проверки равенства между ними. get здесь не поможет, потому что он ничего не знает о другом документе в транзакции, который еще не был написан.

С другой стороны, если вашему правилу необходимо проверить, не изменился ли документ в транзакции на поле в существующем документе (это не текущий проверяемый документ), get необходимо будет извлечь это значение вместо того, чтобы записать транзакцию.

0
ответ дан Doug Stevenson 24 March 2019 в 02:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: