2017-01-04 34 views
5

Trong quá trình ETL tôi cần trích xuất và tải một cột JSON từ cơ sở dữ liệu Postgres này sang cơ sở dữ liệu Postgres khác. Chúng tôi sử dụng Pandas cho điều này vì nó có rất nhiều cách để đọc và ghi dữ liệu từ các nguồn khác nhau/đích và tất cả các phép biến đổi có thể được viết bằng Python và Pandas. Chúng tôi khá hài lòng với cách tiếp cận thành thật nhưng chúng tôi đã gặp phải sự cố.Viết cột JSON vào Postgres bằng Pandas .to_sql

Thông thường, việc đọc và ghi dữ liệu khá dễ dàng. Bạn chỉ cần sử dụng pandas.read_sql_table để đọc dữ liệu từ nguồn và pandas.to_sql để ghi dữ liệu đó đến đích. Tuy nhiên, vì một trong các bảng nguồn có một cột kiểu JSON (từ Postgres), hàm to_sql bị lỗi với thông báo lỗi sau.

df.to_sql(table_name, analytics_db) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/pandas/core/generic.py", line 1201, in to_sql 
    chunksize=chunksize, dtype=dtype) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/pandas/io/sql.py", line 470, in to_sql 
    chunksize=chunksize, dtype=dtype) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/pandas/io/sql.py", line 1147, in to_sql 
    table.insert(chunksize) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/pandas/io/sql.py", line 663, in insert 
    self._execute_insert(conn, keys, chunk_iter) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/pandas/io/sql.py", line 638, in _execute_insert 
    conn.execute(self.insert_statement(), data) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 945, in execute 
    return meth(self, multiparams, params) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection 
    return connection._execute_clauseelement(self, multiparams, params) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement 
    compiled_sql, distilled_params 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context 
    context) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1393, in _handle_dbapi_exception 
    exc_info 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/util/compat.py", line 202, in raise_from_cause 
    reraise(type(exception), exception, tb=exc_tb, cause=cause) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1159, in _execute_context 
    context) 
    File "/home/ec2-user/python-virtual-environments/etl/local/lib64/python2.7/site-packages/sqlalchemy/engine/default.py", line 459, in do_executemany 
    cursor.executemany(statement, parameters) 
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'dict' 

Trả lời

8

Tôi đã tìm kiếm trên web cho một giải pháp nhưng không thể tìm thấy bất kỳ vì vậy đây là những gì chúng tôi đã đưa ra (có thể có những cách tốt hơn nhưng ít nhất đây là một sự khởi đầu nếu ai đó chạy vào này).

Chỉ định tham số dtype trong to_sql.

Chúng tôi đã đi từ: df.to_sql(table_name, analytics_db) đến df.to_sql(table_name, analytics_db, dtype={'name_of_json_column_in_source_table': sqlalchemy.types.JSON}) và nó chỉ hoạt động.

Các vấn đề liên quan