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

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

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

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQLAlchemy

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Python

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

Q&A

解決済

1回答

3363閲覧

SQLAlchemyでForeignKeyのあるテーブルが作成できない

退会済みユーザー

退会済みユーザー

総合スコア0

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQLAlchemy

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Python

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

0グッド

0クリップ

投稿2020/06/01 19:35

編集2020/06/01 23:26

前提・実現したいこと

  • SQLAlchemyを利用して、PosegreSQLのデータベースを作っています。
  • 外部キーを用いたテーブル作成がうまくいきません。下記の2つのテーブルを作りたいです。bs_secondaryテーブルは、外部キーとしてbs_primaryテーブルのidを参照させたいです。

(bs_primary)

idname
1流動資産
2固定資産
3流動負債
4固定負債
5純資産

(bs_secondary)

idnameprimary_id
101現金1
102当座預金1
103普通預金1
  • まず最初にprimaryテーブルを作成しました。これは成功しました。
  • その後にsecondaryテーブルを作成しようとして、失敗しています。

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

NoReferencedTableError Traceback (most recent call last) <ipython-input-27-84edb30c4bec> in <module> 9 10 ---> 11 Base.metadata.create_all(bind=engine) ~\Anaconda3\lib\site-packages\sqlalchemy\sql\schema.py in create_all(self, bind, tables, checkfirst) 4002 self, 4003 checkfirst=checkfirst, -> 4004 tables=tables) 4005 4006 def drop_all(self, bind=None, tables=None, checkfirst=True): ~\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py in _run_visitor(self, visitorcallable, element, connection, **kwargs) 1938 connection=None, **kwargs): 1939 with self._optional_conn_ctx_manager(connection) as conn: -> 1940 conn._run_visitor(visitorcallable, element, **kwargs) 1941 1942 class _trans_ctx(object): ~\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py in _run_visitor(self, visitorcallable, element, **kwargs) 1547 def _run_visitor(self, visitorcallable, element, **kwargs): 1548 visitorcallable(self.dialect, self, -> 1549 **kwargs).traverse_single(element) 1550 1551 ~\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py in traverse_single(self, obj, **kw) 119 meth = getattr(v, "visit_%s" % obj.__visit_name__, None) 120 if meth: --> 121 return meth(obj, **kw) 122 123 def iterate(self, obj): ~\Anaconda3\lib\site-packages\sqlalchemy\sql\ddl.py in visit_metadata(self, metadata) 734 735 collection = sort_tables_and_constraints( --> 736 [t for t in tables if self._can_create_table(t)]) 737 738 seq_coll = [s for s in metadata._sequences.values() ~\Anaconda3\lib\site-packages\sqlalchemy\sql\ddl.py in sort_tables_and_constraints(tables, filter_fn, extra_dependencies) 1093 continue 1094 -> 1095 dependent_on = fkc.referred_table 1096 if dependent_on is not table: 1097 mutable_dependencies.add((dependent_on, table)) ~\Anaconda3\lib\site-packages\sqlalchemy\sql\schema.py in referred_table(self) 3000 3001 """ -> 3002 return self.elements[0].column.table 3003 3004 def _validate_dest_table(self, table): ~\Anaconda3\lib\site-packages\sqlalchemy\util\langhelpers.py in __get__(self, obj, cls) 765 if obj is None: 766 return self --> 767 obj.__dict__[self.__name__] = result = self.fget(obj) 768 return result 769 ~\Anaconda3\lib\site-packages\sqlalchemy\sql\schema.py in column(self) 1889 "foreign key to target column '%s'" % 1890 (self.parent, tablekey, colname), -> 1891 tablekey) 1892 elif parenttable.key not in parenttable.metadata: 1893 raise exc.InvalidRequestError( NoReferencedTableError: Foreign key associated with column 'bs_secondary.bs_primary_id' could not find table 'bs_primary' with which to generate a foreign key to target column 'id'

該当のソースコード

python

1from sqlalchemy import Column, ForeignKey, Integer, String, create_engine 2from sqlalchemy.ext.declarative import declarative_base 3from sqlalchemy.orm import * 4engine = create_engine('postgresql://username:password@127.0.0.1:5432/database_name') 5 6Base = declarative_base() 7 8class BS_PRIMARY(Base): 9 __tablename__ = 'bs_primary' 10 11 id = Column(Integer, primary_key=True, autoincrement=False) 12 name = Column(String) 13 14Base.metadata.create_all(bind=engine)


上記までは成功しました。
下記を実行した所、上記のエラーが出ています。

python

1Base = declarative_base() 2 3class BS_SECONDARY(Base): 4 __tablename__ = 'bs_secondary' 5 6 id = Column(Integer, primary_key=True, autoincrement=False) 7 name = Column(String) 8 bs_primary_id = Column(Integer, ForeignKey("bs_primary.id")) 9 10 11Base.metadata.create_all(bind=engine)

対応策1

  • 一旦、bs_primaryを削除し、bs_primaryとbs_secondaryを同時に作成した所、作成することができました。
  • 後からリレーションの関係のあるテーブルを追加する方法があれば良いのですが、良い方法はあるのでしょうか。

何かお気づきの点ありましたら、ご教示頂ければ幸いです。
よろしくお願い致します。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/06/01 23:11

ありがとうございます。ご指摘の通り、同時に作成したら、出来ました。
guest

回答1

0

ベストアンサー

python

1from sqlalchemy import Column, ForeignKey, Integer, String, create_engine 2from sqlalchemy.ext.declarative import declarative_base 3from sqlalchemy.orm import * 4 5engine = create_engine('postgresql://username:password@127.0.0.1:5432/database_name') 6 7Base = declarative_base() 8 9class BS_PRIMARY(Base): 10 __tablename__ = 'bs_primary' 11 12 id = Column(Integer, primary_key=True, autoincrement=False) 13 name = Column(String) 14 15 16# ここから追加 17class BS_SECONDARY(Base): 18 __tablename__ = 'bs_secondary' 19 20 id = Column(Integer, primary_key=True, autoincrement=False) 21 name = Column(String) 22 bs_primary_id = Column(Integer, ForeignKey("bs_primary.id")) 23 24# 最後にまとめてcreate_all 25Base.metadata.create_all(bind=engine)

これでできました。
追記する時もBS_PRIMARYを記載しなければならないことと、最後にまとめてcreate_allという所が重要でした。

投稿2020/06/06 21:06

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問