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

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

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4986閲覧

sqlalchemyで、データベースの接続が失敗する原因がわからない

bz5adgjmptw0

総合スコア18

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/05/17 07:20

編集2021/05/20 16:24

現在sqlalchemyでmodelを何個か定義してテーブルを作成しようと思っています。
作成の際に参考にしたのはfastAPIのチュートリアルのページです。
外部サーバ上のmysqlデータベースを使用しています。

環境

  • ubuntu20
  • python3.8.5
  • sqlalchemy
  • mysql(外部サーバ上においてあるデータベースを使用)

SSH情報(セキュリティのため仮のものにしています)

  • ホスト名:111.111.111.111
  • ポート:1111
  • SSHユーザ名:testuser
  • SSHパスワード:testpassword

データベース情報

MySQL

  • データベース名:testdb
  • ユーザ名:test
  • パスワード:password
  • ホスト名:localhost

ディレクトリ構成

├── database.py ├── main.py └── models.py

ファイル内容

database.py

from sshtunnel import SSHTunnelForwarder from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, scoped_session with SSHTunnelForwarder( ("111.111.111.111", 1111), ssh_host_key=None, ssh_username="testuser", ssh_password="testpassword", remote_bind_address=("127.0.0.1", 3306), ) as server: DATABASE_URL = f'mysql://{"test"}:{"password"}@localhost:{server.local_bind_port}/{"testdb"}?charset=utf8' ENGINE = create_engine(DATABASE_URL, encoding="utf-8", echo=True) # Sessionの作成 session = scoped_session( sessionmaker(autocommit=False, autoflush=False, bind=ENGINE) )

models.py

from sqlalchemy.orm import relationship from sqlalchemy.ext.declarative import as_declarative, declarative_base, declared_attr from database import session @as_declarative() class Model(object): @declared_attr def __tablename__(cls): return cls.__name__.lower() id = Column(Integer, primary_key=True, index=True) created_at = Column(DateTime, server_default=text("NOW()"), nullable=False) updated_at = Column(DateTime, server_default=text("NOW()"), nullable=False) Base = declarative_base(cls=Model) Base.query = session.query_property() class User(Base): __tablename__ = "users" username = Column(String, unique=True, index=True) password = Column(String) is_active = Column(Boolean) # Relationship exam_result = relationship("ExamResult", back_populates="users")

main.py

from models import Base from database import session, ENGINE # 全テーブル作成 Base.metadata.create_all(bind=ENGINE)

上記の3ファイルにて、main.pyを実行して models.py で定義したテーブルを一括作成しようとしているのですが、
下記のようなエラーが発生しています。

Traceback (most recent call last): File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3141, in _wrap_pool_connect return fn() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 301, in connect return _ConnectionFairy._checkout(self) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 755, in _checkout fairy = _ConnectionRecord.checkout(pool) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 419, in checkout rec = pool._do_get() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 145, in _do_get self._dec_overflow() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ compat.raise_( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 211, in raise_ raise exception File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 142, in _do_get return self._create_connection() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 247, in _create_connection return _ConnectionRecord(self) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 362, in __init__ self.__connect(first_connect_check=True) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 605, in __connect pool.logger.debug("Error on connect(): %s", e) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ compat.raise_( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 211, in raise_ raise exception File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 599, in __connect connection = pool._invoke_creator(self) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/create.py", line 578, in connect return dialect.connect(*cargs, **cparams) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 559, in connect return self.dbapi.connect(*cargs, **cparams) File "/home/kson/.local/lib/python3.8/site-packages/MySQLdb/__init__.py", line 130, in Connect return Connection(*args, **kwargs) File "/home/kson/.local/lib/python3.8/site-packages/MySQLdb/connections.py", line 185, in __init__ super().__init__(*args, **kwargs2) MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)") The above exception was the direct cause of the following exception: Traceback (most recent call last): File "main.py", line 11, in <module> Base.metadata.create_all(bind=ENGINE) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/sql/schema.py", line 4744, in create_all bind._run_ddl_visitor( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3007, in _run_ddl_visitor with self.begin() as conn: File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2923, in begin conn = self.connect(close_with_result=close_with_result) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3095, in connect return self._connection_cls(self, close_with_result=close_with_result) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 91, in __init__ else engine.raw_connection() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3174, in raw_connection return self._wrap_pool_connect(self.pool.connect, _connection) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3144, in _wrap_pool_connect Connection._handle_dbapi_exception_noconnection( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2003, in _handle_dbapi_exception_noconnection util.raise_( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 211, in raise_ raise exception File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 3141, in _wrap_pool_connect return fn() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 301, in connect return _ConnectionFairy._checkout(self) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 755, in _checkout fairy = _ConnectionRecord.checkout(pool) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 419, in checkout rec = pool._do_get() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 145, in _do_get self._dec_overflow() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ compat.raise_( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 211, in raise_ raise exception File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 142, in _do_get return self._create_connection() File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 247, in _create_connection return _ConnectionRecord(self) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 362, in __init__ self.__connect(first_connect_check=True) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 605, in __connect pool.logger.debug("Error on connect(): %s", e) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ compat.raise_( File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 211, in raise_ raise exception File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 599, in __connect connection = pool._invoke_creator(self) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/create.py", line 578, in connect return dialect.connect(*cargs, **cparams) File "/home/kson/.local/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 559, in connect return self.dbapi.connect(*cargs, **cparams) File "/home/kson/.local/lib/python3.8/site-packages/MySQLdb/__init__.py", line 130, in Connect return Connection(*args, **kwargs) File "/home/kson/.local/lib/python3.8/site-packages/MySQLdb/connections.py", line 185, in __init__ super().__init__(*args, **kwargs2) sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)") (Background on this error at: http://sqlalche.me/e/14/e3q8)

考えられる原因

(2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")

が悪さしていると思われます。var/run/mysqld/mysqld.sock を確認したらファイルが存在しなかったため新たに作成してもう一回実行してみましたが、うまく行きませんでした。
なにか考えられる原因がわかる方がいればご教授お願いします。よろしくお願いいたします。

追記

SSHTunnelForwarderを実行しできており、server変数はきちんと取得されています。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/17 07:47

DATABASE_URL = "mysql://%s:%s@%s/%s?charset=utf8" % ( "ユーザ名", "パスワード", "外部サーバのIPアドレス", "データベース名", ) に格納される値は正しいですか? ユーザー名を作成していない場合、root パスワードを設定していない場合、空文字列 外部サーバのIPアドレス、ローカルだと127.0.0.1 データベースは作っているか。 また普段使いにて、mysqlの接続やdatabaseの作成などはターミナル上で可能でしょうか? 再度ご確認のほど、よろしくお願いいたします。????‍♂️
bz5adgjmptw0

2021/05/17 13:28 編集

ご質問ありがとうございます。 ユーザ名, パスワード, 外部IP, ポート, データベース名は例として ユーザ名:test パスワード: password 外部IPアドレス:111.111.111.111 ポート:1111 データベース名:testdb で --------------------------------------------------------------------------- DATABASE_URL = "mysql://%s:%s@%s/%s?charset=utf8" % ( "test", "password", "111.111.111.111:1111", "testdb", ) --------------------------------------------------------------------------- としています。 普段使いにてmysqlの接続やデータベースの作成はターミナル上で可能です。 よろしくお願いします。
退会済みユーザー

退会済みユーザー

2021/05/17 23:52

返信ありがとうございます。 外部IPアドレスの指定がうまくいっていないのかな〜。。 ローカルのmysqlと接続して、sqlalchemyが動作することを確認いただくことは可能でしょうか? --------------------------------------------------------------------------- DATABASE_URL = "mysql://%s:%s@%s/%s?charset=utf8" % ( "test", "password", 127.0.0.1, "testdb", ) --------------------------------------------------------------------------- で実行してみてください。????‍♂️
bz5adgjmptw0

2021/05/18 10:19

やってみたらテーブル作成できました! やはり外部IPアドレスの指定がうまくいっていないみたいですね...
退会済みユーザー

退会済みユーザー

2021/05/18 10:54 編集

なるほど、ナイストライです。一歩前進ですね〜! いくつか試していきましょう。以下に記載することをご確認いただけますか? ・外部IPアドレスと接続する際に、ドライバーの利用はないのだろうか?(https://www.st-hakky-blog.com/entry/2017/08/13/130202) ・どこのDatabaseサーバーを使っているのかわかりませんが、ホスト名とポート番号に間違いはありませんか?(どこのDatabaseサーバーを使ってるとかいただけると、調べる方法などはアドバイスできるかもしれません。) ・Pythonを実行してmigration(table作成)した際に、エラーが出たと思いますが、接続先のCUI, GUI上にエラーログとかは残っていませんか? 少し難しいかもですがご確認のほど、よろしくお願いいたします。????‍♂️
bz5adgjmptw0

2021/05/18 17:28

何度もありがとうございます! - 外部IPアドレスとの接続の際にドライバは使用していません - データベースサーバはmysql-serverを使用しています。追記欄に記載した画像のhostのIPアドレスとポート番号を設定ファイルに記載しています。 - エラーログは残ってないです...すみません
bz5adgjmptw0

2021/05/19 05:54

tera termからの接続は問題なくできます。 ファイアーウォールの設定はしていて、2222にlimitで制限かけています。 記事を参考にして確認してみましたところ、 /etc/mysql/my.cnf #bind-address=0.0.0.0 /etc/hosts.allow mysqld: ALL: allow となっていました。 追記にも載せましたのでご確認お願い致します!
退会済みユーザー

退会済みユーザー

2021/05/19 10:13

なるほど。ファイヤフォールがいけない気がしますね。 特定の外部IPアドレスからの接続を許可する必要がありそうです。反対にそれ以外の外部IPアドレスからはLIMITしてあげると良さそうです。 こちら一度ご確認くださいませ。????‍♂️ ・https://gihyo.jp/admin/serial/01/ubuntu-recipe/0077
bz5adgjmptw0

2021/05/19 12:34

一度試しにファイアーウォールを無効化にしてmain.pyを実行してみたのですが、同様のエラーが発生しています...
退会済みユーザー

退会済みユーザー

2021/05/20 01:45 編集

ファイヤーウォールに関して承知です。。 一つ確認ですが、外部サーバーに対する設定ファイル(/etc/mysql/my.cnf, /etc/hosts.allowファイル)を編集している認識は合っていますか?(ローカルにあるものを編集している予感。)ssh接続して外部サーバーへアクセスして、設定ファイルをみているのか確認している感じです。 その前提で、 > #bind-address=0.0.0.0 bind-address=0.0.0.0 にしないと、コメントアウト扱いになるのではと思っております。 ご確認のほど、よろしくお願いいたします。????‍♂️
bz5adgjmptw0

2021/05/20 09:32 編集

外部サーバに対する設定ファイルを編集しています。コメントアウトしないで実行してみましたがまだうまくいかなかったです、、 しかしここまで付き合っていただいて大変申し訳ないのですが、自分の実現したいこととやっていることが大きく異なることに昨日気付きました... https://blog.honjala.net/entry/2016/06/25/013131 こちらの記事のように、sshトンネリングしてデータベースにアクセスすることがしたかったです。大変余計な労力を使わせてしまってすみません。 そうなるとまた別の設定をする必要があったのでコードを書き直しました。しかし今度は別のエラーが発生しています。追記に記載するので一度ご確認いただけますでしょうか。 大変申し訳ございません。
bsdfan

2021/05/21 07:37

使ったことがないのでわかりませんが、SSHTunnelForwarder を with ブロックで書かれているので、ブロックを抜けた段階でsshのトンネルは閉じられてしまうのではないでしょうか。 そうだとすると、importしたsessionとかENGINEとかは使えないですね。
bz5adgjmptw0

2021/05/21 09:36

withを抜いてやってみたらできました!!!!!!!!!!!!! ありがとうございます!!!
退会済みユーザー

退会済みユーザー

2021/05/21 09:48

> bsdfanさん 適切なアドバイスありがとうございます。 何とかうまくいったみたいで、すごく助かりました。????‍♂️
退会済みユーザー

退会済みユーザー

2021/05/21 09:49

> bz5adgjmptw0さん お、うまくいってよかった〜。 長い戦いお疲れ様でした!! またわからないこととかありましたら、気軽にご相談ください〜!! Enjoy!!!
bz5adgjmptw0

2021/05/21 09:51

> KUROROさん 何度も対応していただきありがとうございます!ぜひまた相談よろしくお願いします!
guest

回答1

0

自己解決

database.pyの、SSHTunnelForwarderをwithでなくserverという変数に入れてやってみたら作成できました。
何度も対応してくださったKUROROさん、アドバイスをくださったbsdfanさんありがとうございました!!

from sshtunnel import SSHTunnelForwarder from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, scoped_session server = SSHTunnelForwarder( ("111.111.111.111", 1111), ssh_host_key=None, ssh_username="testuser", ssh_password="testpassword", remote_bind_address=("127.0.0.1", 3306), ) DATABASE_URL = f'mysql://{"test"}:{"password"}@localhost:{server.local_bind_port}/{"testdb"}?charset=utf8' ENGINE = create_engine(DATABASE_URL, encoding="utf-8", echo=True) session = scoped_session( sessionmaker(autocommit=False, autoflush=False, bind=ENGINE) )

投稿2021/05/21 09:40

bz5adgjmptw0

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問