跨文件的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'
如何在这些文件中共享声明基础?
考虑到我可能会在此之上抛出诸如Pylons或Turbogears之类的东西,什么是“正确”的方法来实现这一点?
编辑10-03-2011
我从描述问题的金字塔框架中find了这个描述,更重要的是validation这是一个实际的问题,而不是(仅)我的困惑自我就是这个问题。 希望能帮助别人敢走这条危险之路:)
解决您的问题最简单的方法是将Base
引出到导入A
, B
和C
的模块中; 打破循环导入。
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()
后创buildBase
和Tables
的文件中导入类。 简单的例子,我的项目是如何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