jov*_*eha 68 python sqlalchemy
我正在试图弄清楚如何将SQLAlchemy类分布在几个文件中,而我可以为生活找不到如何做到这一点.我对SQLAlchemy很新,所以如果这个问题很简单,请原谅我.
在每个自己的文件中考虑这3个类:
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")
Run Code Online (Sandbox Code Playgroud)
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"))
Run Code Online (Sandbox Code Playgroud)
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"))
Run Code Online (Sandbox Code Playgroud)
然后说我们有一个像这样的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 = A.A()
b1 = B.B()
b2 = B.B()
c1 = C.C()
c2 = C.C()
a.Bs.append(b1)
a.Bs.append(b2)
a.Cs.append(c1)
a.Cs.append(c2)
session.add(a)
session.commit()
Run Code Online (Sandbox Code Playgroud)
以上给出了错误:
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'
Run Code Online (Sandbox Code Playgroud)
如何跨这些文件共享声明性基础?
什么是"正确"的方法来实现这一点,考虑到我可能会抛出像Pylons或Turbogears这样的东西?
编辑10-03-2011
我从金字塔框架中找到了这个描述问题的描述,更重要的是验证了这是一个实际的问题而不是(仅)我困惑的自我就是问题.希望它可以帮助那些敢于走这条危险道路的人:)
Sin*_*ion 74
解决问题的最简单方法是Base
取出导入的模块A
,B
并且C
; 打破循环导入.
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
Run Code Online (Sandbox Code Playgroud)
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")
Run Code Online (Sandbox Code Playgroud)
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"))
Run Code Online (Sandbox Code Playgroud)
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"))
Run Code Online (Sandbox Code Playgroud)
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 = 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()
Run Code Online (Sandbox Code Playgroud)
适用于我的机器:
$ python main.py ; echo $?
0
Run Code Online (Sandbox Code Playgroud)
小智 8
我正在使用Python 2.7 + Flask 0.10 + SQLAlchemy 1.0.8 + Postgres 9.4.4.1
该样板配置有User和UserDetail模型,这些模型存储在"user"模块中的同一文件"models.py"中.这些类都继承自SQLAlchemy基类.
我添加到项目中的所有其他类也派生自此基类,并且随着models.py文件变大,我决定将models.py文件拆分为每个类的一个文件,并遇到所描述的问题这里.
我发现的解决方案与@ computermacgyver 2013年10月23日的帖子一样,是将我的所有类都包含在我创建的新模块的init .py文件中,以保存所有新创建的类文件.看起来像这样:
/project/models/
__init__.py contains
from project.models.a import A
from project.models.b import B
etc...
Run Code Online (Sandbox Code Playgroud)
如果我也遇到同样的问题,我也可以增加一点理智。您需要导入,你创建的文件中的类Base = declarative_base()
创建的AFTER Base
和Tables
。简短示例如何设置我的项目:
型号/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')
Run Code Online (Sandbox Code Playgroud)
型号/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'))
Run Code Online (Sandbox Code Playgroud)
型号/__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
Run Code Online (Sandbox Code Playgroud)