質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.06%

pandasのto_sqlでPostgreSQLにデータを書き込もうとするとエラー

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,866

score 11

前提・実現したいこと

PostgreSQLにPandasのto_sqlでデータを書き込もうとすると、以下のエラーが出力されます
AttributeError: 'Engine' object has no attribute 'cursor'
sqlalchemyのcreate_engineでengineを変更しているはずなのですが、うまくいきません。 
pandasのversionで何か変更があったのでしょうか…?
それともpandasとsqlalchemyのバージョンの相性があるのでしょうか…?

ソースコード

import pandas as pd
import psycopg2
from sqlalchemy import create_engine

df=pd.DataFrame(np.arange(6).reshape(2,3),columns=["a","b","c"]) #適当なDataFrame

connection_config = {
    'user': 'postgres',
    'password': 'hogehoge',
    'host': 'fugafuga',
    'port': '5432',
    'database': 'sampledb'
}

engine = create_engine('postgresql://{user}:{password}@{host}:{port}/{database}'.format(**connection_config),echo=False)
df.to_sql("table_test",con=engine,if_exists="replace")

発生しているエラーメッセージ

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-132-d290ff87c057> in <module>
----> 1 df.to_sql("table_test3",con=engine,if_exists="replace")

~\Miniconda3\envs\py\lib\site-packages\pandas\core\generic.py in to_sql(self, name, con, schema, if_exists, index, index_label, chunksize, dtype, method)
   2710             chunksize=chunksize,
   2711             dtype=dtype,
-> 2712             method=method,
   2713         )
   2714 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in to_sql(frame, name, con, schema, if_exists, index, index_label, chunksize, dtype, method)
    516         chunksize=chunksize,
    517         dtype=dtype,
--> 518         method=method,
    519     )
    520 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in to_sql(self, frame, name, if_exists, index, index_label, schema, chunksize, dtype, method)
   1747             dtype=dtype,
   1748         )
-> 1749         table.create()
   1750         table.insert(chunksize, method)
   1751 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in create(self)
    639 
    640     def create(self):
--> 641         if self.exists():
    642             if self.if_exists == "fail":
    643                 raise ValueError(

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in exists(self)
    626 
    627     def exists(self):
--> 628         return self.pd_sql.has_table(self.name, self.schema)
    629 
    630     def sql_schema(self):

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in has_table(self, name, schema)
   1760         ).format(wld=wld)
   1761 
-> 1762         return len(self.execute(query, [name]).fetchall()) > 0
   1763 
   1764     def get_table(self, table_name, schema=None):

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in execute(self, *args, **kwargs)
   1588             cur = self.con
   1589         else:
-> 1590             cur = self.con.cursor()
   1591         try:
   1592             if kwargs:

AttributeError: 'Engine' object has no attribute 'cursor'

試したこと

stackoverflowに以下を試してみて!との記載を見つけたので確認しましたが、以下のような結果でした。
そのあとのコメントは途絶えており参考にできませんでした。

import sqlalchemy
isinstance(engine,sqlalchemy.engine.Engine)
#結果: True

pd.io.sql._is_sqlalchemy_connectable(engine)
#結果: False

sqlalchemyのサイトを見ると、以下のようにあったので、試しにengine = create_engine('postgresql+psycopg2://<接続定義>')のようにしてみましたが、結果は変わらずでした。

The PostgreSQL dialect uses psycopg2 as the default DBAPI. pg8000 is also available as a pure-Python substitute:

# default
engine = create_engine('postgresql://scott:tiger@localhost/mydatabase')

# psycopg2
engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')

# pg8000
engine = create_engine('postgresql+pg8000://scott:tiger@localhost/mydatabase')

engine=engine.connect()としてみて」との記載もあったのですが、結果変わらずです。こちらはsqliteへの書き込み処理に関する質問に記載されていたので的外れかもしれませんが…。

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-186-d290ff87c057> in <module>
----> 1 df.to_sql("table_test3",con=engine,if_exists="replace")
(省略)
AttributeError: 'Connection' object has no attribute 'cursor'

engine=engine.raw_connection()としたらうまくいったよ」とのstackoverflowを見つけたので試してみましたが、また別のエラーになりました。こちらも上記同様、sqliteへの書き込み処理に関する手順みたいなので、本件とは的外れだと思いますが…。

---------------------------------------------------------------------------
UndefinedTable                            Traceback (most recent call last)
~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in execute(self, *args, **kwargs)
   1594             else:
-> 1595                 cur.execute(*args)
   1596             return cur

UndefinedTable: リレーション"sqlite_master"は存在しません
LINE 1: SELECT name FROM sqlite_master WHERE type='table' AND name=?...
                         ^


During handling of the above exception, another exception occurred:

DatabaseError                             Traceback (most recent call last)
<ipython-input-144-712d0d3b6b3e> in <module>
      1 # PostgreSQLに書き込む
----> 2 df.to_sql('table_test2', con=engine, if_exists='replace', index=False)

~\Miniconda3\envs\py\lib\site-packages\pandas\core\generic.py in to_sql(self, name, con, schema, if_exists, index, index_label, chunksize, dtype, method)
   2710             chunksize=chunksize,
   2711             dtype=dtype,
-> 2712             method=method,
   2713         )
   2714 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in to_sql(frame, name, con, schema, if_exists, index, index_label, chunksize, dtype, method)
    516         chunksize=chunksize,
    517         dtype=dtype,
--> 518         method=method,
    519     )
    520 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in to_sql(self, frame, name, if_exists, index, index_label, schema, chunksize, dtype, method)
   1747             dtype=dtype,
   1748         )
-> 1749         table.create()
   1750         table.insert(chunksize, method)
   1751 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in create(self)
    639 
    640     def create(self):
--> 641         if self.exists():
    642             if self.if_exists == "fail":
    643                 raise ValueError(

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in exists(self)
    626 
    627     def exists(self):
--> 628         return self.pd_sql.has_table(self.name, self.schema)
    629 
    630     def sql_schema(self):

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in has_table(self, name, schema)
   1760         ).format(wld=wld)
   1761 
-> 1762         return len(self.execute(query, [name]).fetchall()) > 0
   1763 
   1764     def get_table(self, table_name, schema=None):

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in execute(self, *args, **kwargs)
   1608                 "Execution failed on sql '{sql}': {exc}".format(sql=args[0], exc=exc)
   1609             )
-> 1610             raise_with_traceback(ex)
   1611 
   1612     @staticmethod

~\Miniconda3\envs\py\lib\site-packages\pandas\compat\__init__.py in raise_with_traceback(exc, traceback)
     44     if traceback == Ellipsis:
     45         _, _, traceback = sys.exc_info()
---> 46     raise exc.with_traceback(traceback)
     47 
     48 

~\Miniconda3\envs\py\lib\site-packages\pandas\io\sql.py in execute(self, *args, **kwargs)
   1593                 cur.execute(*args, **kwargs)
   1594             else:
-> 1595                 cur.execute(*args)
   1596             return cur
   1597         except Exception as exc:

DatabaseError: Execution failed on sql 'SELECT name FROM sqlite_master WHERE type='table' AND name=?;': リレーション"sqlite_master"は存在しません
LINE 1: SELECT name FROM sqlite_master WHERE type='table' AND name=?...
                         ^

to_sqlの使い方を紹介するページには特に何の言及もないようなので、どうすべきかわかりません。
何が原因なのか、当方でどうトラブルシュートしていけばいいか、当方もpython初心者につき見当がつきません…。
何卒ご助力いただきたくよろしくお願いします。

参考にしたページ

[Qiita][python] pandasのDataFrameからpostgresにテーブルを作成(2016年09月30日)
[その他]PandasのDataFrameでPostgreSQLに読み書きする方法(2020年1月15日)
[teratail]pandasのdataframeをto_sqlするとDatabaseErrorになる(解決済 回答2 投稿 2018/02/20 13:18)
[stackoverflow]Writing to PostgreSQL from pandas: AttributeError: 'Engine' object has no attribute 'cursor'( Asked 4 years, 3 months ago Viewed 2k times )

バージョン

Python 3.7.4
pandas 0.25.1
psycopg2 2.8.4 (dt dec pq3 ext lo64)
sqlalchemy 1.3.15
postgres PostgreSQL 10.11, compiled by Visual C++ build 1800, 64-bit

補足事項

pythonのターミナルで直書きしたら、特にエラーなくいけました。
開発環境としてjupyter notebookを使っているのですが、まさかこれが原因……??
ご意見いただきたくよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

schema='piyopiyo'を設定してなかっただけでした。

df.to_sql(name="table_test",schema='schema_test',con=engine,if_exists="replace",index=False)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る