我试图遵循上一个与 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
(空的)
主文件
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 文件中解决了这个问题(描述为下面的一个答案),但有谁知道为什么这会在 python3 中产生错误而在 python2 中没有?首先是什么变化导致了这种情况?