2017-01-04 17 views
5

ETLの処理中に、1つのPostgresデータベースから別のPostgresデータベースにJSON列を抽出して読み込む必要がありました。これは、さまざまなソース/デスティネーションからデータを読み書きする方法が非常に多く、PythonとPandasを使用してすべての変換を記述できるため、Pandasを使用しています。私たちは正直な考え方にはとても満足しています。しかし、私たちは問題にぶつかりました。Pandas .to_sqlを使用してPostgresにJSON列を書き込む

通常、データの読み書きは非常に簡単です。ソースからのデータを読むにはpandas.read_sql_tableを使用し、宛先に書き込むにはpandas.to_sqlを使用します。しかし、ソーステーブルの1つにJSON(Postgres製)の列があるため、to_sql関数が次のエラーメッセージでクラッシュしました。私たちが思い付いたものです

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' 

答えて

8

私は解決策のためのWebを検索してきたが、どのので、ここで見つけることができませんでした(そこより良い方法であることが、他の誰かがこのに実行されている場合、少なくともこれがスタートですかもしれません)。

dtypeパラメータをto_sqlに指定します。

私たちは:df.to_sql(table_name, analytics_db)からdf.to_sql(table_name, analytics_db, dtype={'name_of_json_column_in_source_table': sqlalchemy.types.JSON})になりました。

関連する問題