Как решить InterfaceError при импорте файла переменной, в которой переменная глубины 1 является списком? - PullRequest
0 голосов
/ 05 июля 2019

Я импортирую переменный файл (например, variables.json) в поток воздуха, в котором одна переменная глубины-1 представляет собой следующий список:

{...

"var1": ["value1", "value2"],

...

}

Я пробовал 3 метода:

1). в командной строке: переменные воздушного потока -i variables.json

2). в интерфейсе airflow, admin -> Variables -> Choose file -> Import Variables

3). в интерфейсе воздушного потока admin -> Variables -> Create -> ключ ввода (т. е. Var1) и значение (т. е. ["value1", "value2"]) соответственно.

Метод 1 и 2 не удался, но успешно 3.

метод 1 возвращает информацию типа «15 из 27 переменных успешно обновлены», что означает, что некоторые переменные не были успешно обновлены

метод 2 показывает ошибку: InterfaceError: (sqlite3.InterfaceError) Ошибка привязки параметра 1 - возможно, неподдерживаемый тип. [SQL: переменная u'INSERT INTO («ключ», val, is_encrypted) ЗНАЧЕНИЯ (?,?,?) '] [Параметры: (u'var1', [u'value1 ', u'value2'], 0) ] (Справочная информация об этой ошибке: http://sqlalche.me/e/rvf5)

Я нашел и нашел эту тему: InterfaceError: (sqlte3.InterfaceError) Ошибка параметра привязки 0 . Похоже, что sqlite не поддерживает тип списка.

Я также проверил случай, когда переменная вложенности (здесь, например, var2_1) была списком, подобным этому

{...

"var2": {"var2_1": ["A", "B"]},

... }

все вышеперечисленные 3 метода работают.

Итак, мои вопросы:

(1), почему метод 1 и 2 потерпел неудачу, но 3 успешно для переменной глубины 1, являющейся списком?

(2) почему вложенная переменная (deep-2,3, ...) может быть списком без проблем?

Ответы [ 2 ]

0 голосов
/ 06 июля 2019

Если вы используете Airflow 1.10.3, import_helper, используемый в CLI, сериализует только значения dict до JSON.

def import_helper(filepath):
    #...
            for k, v in d.items():
                if isinstance(v, dict):
                    Variable.set(k, v, serialize_json=True)
                else:
                    Variable.set(k, v)
                n += 1
        except Exception:
            pass
        finally:
            print("{} of {} variables successfully updated.".format(n, len(d)))

https://github.com/apache/airflow/blob/1.10.3/airflow/bin/cli.py#L376

Импортер WebUI также делает то же самое со значениями dict.

models.Variable.set(k, v, serialize_json=isinstance(v, dict))

https://github.com/apache/airflow/blob/1.10.3/airflow/www/views.py#L2073

Однако текущая версия (1.10.4rc1) показывает, что не строковые значения будут сериализованы в строковые в будущих выпусках в CLI import_helper

Variable.set(k, v, serialize_json=not isinstance(v, six.string_types))

https://github.com/apache/airflow/blob/1.10.4rc1/airflow/bin/cli.py

... и импортер WebUI.

models.Variable.set(k, v, serialize_json=not isinstance(v, six.string_types))

https://github.com/apache/airflow/blob/1.10.4rc1/airflow/www/views.py#L2118

В настоящее время он будет выполнять сериализацию нестроковых значений в процессе импорта, когда вы делаете это с помощью интерфейса импорта CLI или WebUI.

... и когда вы получаете значение для такой переменной, передайте опцию десериализации их например,

Variable.get('some-key', deserialize_json=True)
0 голосов
/ 05 июля 2019

В вашем variable.json ["value1", "value2"] - это массив, в котором Airflow ожидает значение / строку или JSON. Это сработает, если вы приведете этот массив в строку в вашем JSON.

...