Как сжать результаты запроса-Python / Airflow - PullRequest
0 голосов
/ 07 февраля 2020

Я пытаюсь GZIP результаты моего запроса и записать его в местоположение в Airflow. Однако я получаю сообщение об ошибке

TypeError: memoryview: требуется байтоподобный объект, а не 'str'

всякий раз, когда я запускаю свой код.

Проверьте переменную fp в моем коде:

def create_tunnel_postgres():
    try:
        tunnel = SSHTunnelForwarder((ssh_host, 22),
                                    ssh_username=ssh_username,
                                    ssh_private_key=pkf,
                                    remote_bind_address=(psql_host,
                                    5432))

            # local_bind_address=('localhost',6543) # could be any available port
        # Start the tunnel

        tunnel.start()
    except:
        print 'connection'
    else:
        conn = psycopg2.connect(database='my_db', user='user',
                                password='my_pwd',
                                host=tunnel.local_bind_host,
                                port=tunnel.local_bind_port)

        cur = conn.cursor()
        cur.execute("""
            select * from pricing.public.seller_tiers ;
            """)
        result = cur.fetchall()

        # Getting Field Header names

        column_names = [i[0] for i in cur.description]
        fp = gzip.open(path, 'wb')
        myFile = csv.writer(fp, delimiter=',')
        myFile.writerow(column_names)
        myFile.writerows(result)
        fp.close()
        conn.close
        tunnel.stop

Есть идеи или предложения? Я новичок в python / airflow, так что все поможет.

1 Ответ

0 голосов
/ 08 февраля 2020

Я думаю, что ошибка будет связана с тем, как вы используете содержимое файла gzip writer.

Вы пытаетесь открыть файл gzip в байтовом режиме и записать в него строку, здесь fp = gzip.open(path, 'wb') .

Согласно документации python в здесь указано:

'rt', 'at', 'wt' или 'xt' для текстовый режим.

Измените код для использования wt, который является записью текста, или используйте функцию кодирования для кодирования в байты:

 import gzip
 import csv

 with gzip.open("sample.gz", "wt") as gz_fp:
     fieldnames = ['first_name', 'last_name']
     writer = csv.writer(gz_fp, delimiter=",")

     writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
     writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
     writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})

Если вы хотите записывать байты только тогда :

with gzip.open('file.gz', 'wb') as f:
    f.write('Hello world!'.encode())
...