Панда дает максимальную глубину рекурсии превышен: RecursionError на AWS Lambda, отлично работает локально - PullRequest
0 голосов
/ 08 февраля 2019

Написал лямбда-функцию AWS для проведения некоторых ETL при загрузке данных из RDS в Redshift.Одной из проблем было то, что MySQL имел не-ASCII-символы, которые были бы преобразованы в символы, такие как несколько периодов, что в конечном итоге привело бы к увеличению длины после определения DDL.

Один из шагов, которые я добавил в сценарий ETLдолжен был увидеть, была ли длина строки больше максимальной длины (давайте назовем это n), и если бы это было так, я бы использовал функцию apply так, чтобы использовались только первые 'n' символов строки.

Это работало нормально во всех таблицах, на которых я запускал эту функцию, кроме одной.В рассматриваемой таблице имеется большое количество столбцов (~ 450), которые могут иметь какое-то отношение к тому, почему что-то идет не так.Это работало хорошо, когда я управлял этим локально как бы то ни было.(Local = Python 3.6.6, Lambda использует Python 3.6 runtime)

def clean_data(table, meta_data):
    for col in meta_data[meta_data['type'].apply(lambda s: True if 'varchar' in s else False)]['column']:
        table[col] = table[col].apply(lambda s: s.replace("\x00*\x00", "").replace("\x00", "") if s is not None else s) 
#The above step removes null byte characters
        table[col] = table[col].apply(lambda s: replace_non_ascii(s) if s is not None else s)
#The above step removes non-ASCII characters
        l = int(meta_data[meta_data['column']==col]['length'].iloc[0])
        #The above line is where things go wrong
        table[col] = table[col].apply(lambda s: s[:min(l, len(s))] if s is not None else s)

Stacktrace:

maximum recursion depth exceeded: RecursionError
Traceback (most recent call last):
File "/var/task/table_etl.py", line 268, in table_loader
migratation_start(RDS_TABLE, RS_TABLE, RS_UPDATE_DATE, RDS_COLUMNS)
File "/var/task/table_etl.py", line 257, in migratation_start
migrate_table(rds_table, rs_table, get_rds_conditions(rds_table, rs_table, latest_update_date, latest_id, rs_update_date), rds_cols_str, rds_cols_str2)
File "/var/task/table_etl.py", line 190, in migrate_table
migrate_table_parts(rds_table, rs_table, condition, rds_cols_str, rds_cols_str2)
File "/var/task/table_etl.py", line 181, in migrate_table_parts
rds_data, rds_table_meta = clean_data(rds_data, rds_table_meta)
File "/var/task/table_etl.py", line 163, in clean_data
l = int(meta_data[meta_data['column']==col]['length'].iloc[0])
File "/var/task/pandas/core/ops.py", line 1728, in wrapper
(is_extension_array_dtype(other) and not is_scalar(other))):
File "/var/task/pandas/core/dtypes/common.py", line 1749, in is_extension_array_dtype
registry.find(dtype) is not None)
File "/var/task/pandas/core/dtypes/dtypes.py", line 89, in find
return dtype_type.construct_from_string(dtype)
File "/var/task/pandas/core/dtypes/dtypes.py", line 938, in construct_from_string
return cls(string)
File "/var/task/pandas/core/dtypes/dtypes.py", line 899, in __new__
subtype = pandas_dtype(subtype)
File "/var/task/pandas/core/dtypes/common.py", line 2004, in pandas_dtype
result = registry.find(dtype)
File "/var/task/pandas/core/dtypes/dtypes.py", line 89, in find
return dtype_type.construct_from_string(dtype)
File "/var/task/pandas/core/dtypes/dtypes.py", line 938, in construct_from_string
return cls(string)
File "/var/task/pandas/core/dtypes/dtypes.py", line 899, in __new__
subtype = pandas_dtype(subtype)
File "/var/task/pandas/core/dtypes/common.py", line 2004, in pandas_dtype
result = registry.find(dtype)
File "/var/task/pandas/core/dtypes/dtypes.py", line 89, in find
return dtype_type.construct_from_string(dtype)
File "/var/task/pandas/core/dtypes/dtypes.py", line 938, in construct_from_string
return cls(string)
File "/var/task/pandas/core/dtypes/dtypes.py", line 899, in __new__
subtype = pandas_dtype(subtype)
....

find -> construct_from_string -> _ _ new _ _ -> pandas_dtype, похоже,повторяйте бесконечно, пока не выйдет предел рекурсии.

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

...