问题在于导入。我应该做的是写:from SomeInterface import SomeInterface
。我真的应该根据Python styleguide (PEP 8)以小写someinterface.py
编写模块名称。
我有一个文件model.py
,它定义了与我的数据库相关的所有类,并实例化了我的Base。
# model.py
metadata = MetaData()
DeclarativeBase = declarative_base()
metadata = DeclarativeBase.metadata
class Bar(DeclarativeBase):
__tablename__ = 'Bar'
__table_args__ = {}
# column and relation definitions
文件model.py
是自动生成的,所以我无法触及它。我所做的是创建一个名为modelaugmented.py
的文件,我通过继承为一些模型类添加额外的功能。
# modelaugmented.py
from model import *
import SomeInterface
class BarAugmented(Bar, SomeInterface):
pass
# SomeInterface.py
class SomeInterface(object):
some_method(): pass
我遇到的问题是,对于像BarAugmented
这样的课程,我收到以下错误:
TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
当SomeInterface
位于单独的文件中而不是位于modelaugmented.py
内时,我才会收到此错误。
我了解SomeInterface
和Bar
的元类不同。问题是我无法弄清楚如何解决这个问题。我尝试了Triple inheritance causes metaclass conflict... Sometimes中建议的解决方案,该解决方案适用于给出的示例,但不是我的情况。不确定SqlAlchmey是否与它有任何关系。
class MetaAB(type(DeclarativeBase), type(SomeInterface)):
pass
class BarAugmented(Bar, SomeInterface):
__metaclass__ = MetaAB
但后来我收到了错误:
TypeError: Error when calling the metaclass
bases multiple bases have instance lay-out conflict
使用SQLAlchemy 0.8和Python 2.7。
答案 0 :(得分:1)
好的,一定有一些我不知道的东西,因为我为你创建了一个类似的文件布局(我认为),它可以在我的机器上运行。我很感激你让你的问题简短而简单,但也许缺少一些改变......的东西? Dunno ......(也许SomeInterface
有一个abc.abstract
元类?)如果您更新了问题,请通过对此答案的评论告诉我,我会尝试更新我的答案。
这就是:
档案stack29A.py
(相当于您的model.py
):
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
DSN = "mysql://root:foobar@localhost/so_tests?charset=utf8"
engine = create_engine(DSN)
Session = scoped_session(sessionmaker(bind=engine))
session = Session()
DeclarativeBase = declarative_base()
class Bar(DeclarativeBase):
__tablename__ = 'Bar'
_id = Column('_id', Integer, primary_key=True)
email = Column('email', String(50))
档案stack29B.py
(相当于您的someinterface.py
):
class SomeInterface(object):
def some_method(self):
print "hellou"
档案stack29C.py
(相当于您的modelaugmented.py
):
from stack29A import Bar
from stack29B import SomeInterface
class BarAugmented(Bar, SomeInterface):
pass
文件stack29D.py
(就像一种main.py
:表创建者和示例):
from stack29C import BarAugmented
from stack29A import session, engine, DeclarativeBase
if __name__ == "__main__":
DeclarativeBase.metadata.create_all(engine)
b1 = BarAugmented()
b1.email = "foo@bar.baz"
b2 = BarAugmented()
b2.email = "baz@bar.foo"
session.add_all([b1, b2])
session.commit()
b3 = session.query(BarAugmented)\
.filter(BarAugmented.email == "foo@bar.baz")\
.first()
print "b3.email: %s" % b3.email
b3.some_method()
如果我运行" main"文件(stack29D.py
)一切都按预期工作:
(venv_SO)borrajax@borrajax:~/Documents/Tests$ python ./stack29D.py
b3.email: foo@bar.baz
hellou