SQLAlchemy に関連するこの前の質問に示されている設計パターンに従おうとしていて、複数のファイルで共通の Base インスタンスを共有することを意図していました。このコードは、python2 と python3 でまったく同じように機能します。
ただし、ファイル a.py、b.py、c.py、および base.py をモジュール (モデルと呼ばれる) に移動し、必要な __init__.py ファイルを追加すると、python2 で引き続き動作しますが、エラーが発生します。 python3 上 (詳細は以下)。
次のファイルがあります。
モデル/base.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
モデル/a.py
from sqlalchemy import *
from base import Base
from sqlalchemy.orm import relationship
class A(Base):
__tablename__ = "A"
id = Column(Integer, primary_key=True)
Bs = relationship("B", backref="A.id")
Cs = relationship("C", backref="A.id")
モデル/b.py
from sqlalchemy import *
from base import Base
class B(Base):
__tablename__ = "B"
id = Column(Integer, primary_key=True)
A_id = Column(Integer, ForeignKey("A.id"))
モデル/c.py
from sqlalchemy import *
from base import Base
class C(Base):
__tablename__ = "C"
id = Column(Integer, primary_key=True)
A_id = Column(Integer, ForeignKey("A.id"))
モデル/__init__.py
(空の)
main.py
from sqlalchemy import create_engine
from sqlalchemy.orm import relationship, backref, sessionmaker
from model import base
from model import a
from model import b
from model import c
engine = create_engine("sqlite:///:memory:")
base.Base.metadata.create_all(engine, checkfirst=True)
Session = sessionmaker(bind=engine)
session = Session()
a1 = a.A()
b1 = b.B()
b2 = b.B()
c1 = c.C()
c2 = c.C()
a1.Bs.append(b1)
a1.Bs.append(b2)
a1.Cs.append(c1)
a1.Cs.append(c2)
session.add(a1)
session.commit()
python2 は動作します:
$ python main.py ; echo $?
0
python3 エラー:
$ python3 main.py ; echo $?
Traceback (most recent call last):
File "main.py", line 7, in <module>
from model import a
File "/home/shale/code/py/try/model/a.py", line 2, in <module>
from base import Base
ImportError: No module named base
1
最終的に、base.py のコードを __init__.py ファイルに入れることでこれを解決しました (以下の 1 つの回答として説明)。そもそもこれの原因はどのような変化ですか?