Zgodnie z Twoim traceback, Twój kod łamie się w ten punkt . Jak widać, przetwarza kod:
json.dump(row_dict, tmp_file_handle)
tmp_file_handle
jest NamedTemporaryFile
zainicjowane
z domyślnymi argumentami wejściowymi, to znaczy symuluje plik otwarty za pomocą w+b
tryb (i dlatego akceptuje tylko dane bajtowe jako dane wejściowe).
Problem polega na tym, że w Pythonie 2 wszystkie ciągi są bajtami, podczas gdy w Pythonie 3 ciągi są tekstami (domyślnie zakodowane jako utf-8
).
Jeśli otworzysz Pythona 2 i uruchomisz ten kod:
In [1]: from tempfile import NamedTemporaryFile
In [2]: tmp_f = NamedTemporaryFile(delete=True)
In [3]: import json
In [4]: json.dump({'1': 1}, tmp_f)
Działa dobrze.
Ale jeśli otworzysz Pythona 3 i uruchomisz ten sam kod:
In [54]: from tempfile import NamedTemporaryFile
In [55]: tmp_f = NamedTemporaryFile(delete=True)
In [56]: import json
In [57]: json.dump({'1': 1}, tmp_f)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-57-81743b9013c4> in <module>()
----> 1 json.dump({'1': 1}, tmp_f)
/usr/local/lib/python3.6/json/__init__.py in dump(obj, fp, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
178 # a debuggability cost
179 for chunk in iterable:
--> 180 fp.write(chunk)
181
182
/usr/local/lib/python3.6/tempfile.py in func_wrapper(*args, **kwargs)
481 @_functools.wraps(func)
482 def func_wrapper(*args, **kwargs):
--> 483 return func(*args, **kwargs)
484 # Avoid closing the file as long as the wrapper is alive,
485 # see issue #18879.
TypeError: a bytes-like object is required, not 'str'
Otrzymujemy ten sam błąd, co Twój.
Oznacza to, że Airflow nadal nie jest w pełni obsługiwany dla Pythona 3 (jak widać w pokrycie testowe
, moduł airflow/contrib/operators/mysql_to_gcs.py
nie jest jeszcze testowany ani w Pythonie 2 ani 3). Jednym ze sposobów potwierdzenia tego byłoby uruchomienie kodu za pomocą Pythona 2 i sprawdzenie, czy działa.
Zalecam utworzenie zgłoszenia w ich JIRA żądając przenośności dla obu wersji Pythona.