跨文件的SQLAlchemy类

我想弄清楚如何让SQLAlchemy类传播到几个文件中,而且我终身不知道如何去做。 我对SQLAlchemy很新,所以原谅我,如果这个问题是微不足道的..

考虑这三个类在他们自己的文件中

A.py:

from sqlalchemy import * from main import Base 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 main 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 main import Base class C(Base): __tablename__ = "C" id = Column(Integer, primary_key=True) A_id = Column(Integer, ForeignKey("A.id")) 

然后说我们有一个main.py这样的东西:

 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, backref, sessionmaker Base = declarative_base() import A import B import C engine = create_engine("sqlite:///test.db") Base.metadata.create_all(engine, checkfirst=True) Session = sessionmaker(bind=engine) session = Session() a = AA() b1 = BB() b2 = BB() c1 = CC() c2 = CC() a.Bs.append(b1) a.Bs.append(b2) a.Cs.append(c1) a.Cs.append(c2) session.add(a) session.commit() 

以上给出了错误:

 sqlalchemy.exc.NoReferencedTableError: Foreign key assocated with column 'C.A_id' could not find table 'A' with which to generate a foreign key to target column 'id' 

如何在这些文件中共享声明基础?

考虑到我可能会在此之上抛出诸如PylonsTurbogears之类的东西,什么是“正确”的方法来实现这一点?

编辑10-03-2011

我从描述问题的金字塔框架中find了这个描述,更重要的是validation这是一个实际的问题,而不是(仅)我的困惑自我就是这个问题。 希望能帮助别人敢走这条危险之路:)

解决您的问题最简单的方法是将Base引出到导入ABC的模块中; 打破循环导入。

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")) 

main.py

 from sqlalchemy import create_engine from sqlalchemy.orm import relationship, backref, sessionmaker import base import a import b import c engine = create_engine("sqlite:///:memory:") base.Base.metadata.create_all(engine, checkfirst=True) Session = sessionmaker(bind=engine) session = Session() a1 = aA() b1 = bB() b2 = bB() c1 = cC() c2 = cC() a1.Bs.append(b1) a1.Bs.append(b2) a1.Cs.append(c1) a1.Cs.append(c2) session.add(a1) session.commit() 

在我的机器上工作:

 $ python main.py ; echo $? 0 

我正在使用Python 2.7 + Flask 0.10 + SQLAlchemy 1.0.8 + Postgres 9.4.4.1

这个样板configuration有一个User和UserDetail模型,存储在“user”模块的相同文件“models.py”中。 这些类都从SQLAlchemy基类inheritance。

我添加到我的项目中的所有附加类也是从这个基类派生的,随着models.py文件变大,我决定将models.py文件拆分成每个类一个文件,并且遇到了描述的问题这里。

我发现的解决scheme,与@ computermacgyver 2013年10月23日发布的一样,是将我所有的类都包含到我创build的新模块的init .py文件中,以保存所有新创build的类文件。 看起来像这样:

 /project/models/ __init__.py contains from project.models.a import A from project.models.b import B etc... 

如果我可以补充一下我的感觉,因为我有同样的问题。 您需要在创buildBase = declarative_base()后创buildBaseTables的文件中导入类。 简单的例子,我的项目是如何build立的:

模型/ user.py

 from sqlalchemy import * from sqlalchemy.orm import relationship from model import Base class User(Base): __tablename__ = 'user' id = Column(Integer, primary_key=True) budgets = relationship('Budget') 

模型/ budget.py

 from sqlalchemy import * from model import Base class Budget(Base): __tablename__ = 'budget' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('user.id')) 

模型/ __ init__.py

 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker _DB_URI = 'sqlite:///:memory:' engine = create_engine(_DB_URI) Base = declarative_base() Base.metadata.create_all(engine) DBSession = sessionmaker(bind=engine) session = DBSession() from .user import User from .budget import Budget