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 = 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()
위의 오류는 다음과 같습니다.
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 와 같은 것을 이 위에 던질 수 있다는 점을 고려할 때 “올바른”방법은 무엇입니까 ?
2011 년 3 월 10 일 수정
나는 문제를 설명하는 Pyramids 프레임 워크 에서이 설명을 찾았고 , 더 중요한 것은 이것이 문제인 내 혼란스러워하는 자신이 아니라 실제 문제임을 확인 하는 것입니다. 이 위험한 길을 감히 도전하는 다른 사람들을 도울 수 있기를 바랍니다. 🙂
답변
문제에 대한 가장 간단한 솔루션을 가지고하는 것입니다 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 = 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()
내 컴퓨터에서 작동 :
$ python main.py ; echo $?
0
답변
같은 문제가 있었기 때문에 약간의 감각을 더할 수 있다면. Base = declarative_base()
을 만든 후 파일 을 만든 파일에서 클래스를 가져와야 Base
합니다 Tables
. 내 프로젝트 설정 방법의 간단한 예 :
model / 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')
model / 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'))
model / __ 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
답변
Python 2.7 + Flask 0.10 + SQLAlchemy 1.0.8 + Postgres 9.4.4.1을 사용하고 있습니다.
이 상용구는 “user”모듈의 동일한 파일 “models.py”에 저장된 User 및 UserDetail 모델로 구성됩니다. 이러한 클래스는 모두 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...
답변
저에게는 import app.tool.tool_entity
내부 app.py
와 from app.tool.tool_entity import Tool
내부를 추가하는 tool/__init__.py
것만으로도 테이블을 만들 수있었습니다. 나는 아직 관계를 추가하려고 시도하지 않았습니다.
폴더 구조 :
app/
app.py
tool/
__init__.py
tool_entity.py
tool_routes.py
# app/tool/tool_entity.py
from app.base import Base
from sqlalchemy import Column, Integer, String
class Tool(Base):
__tablename__ = 'tool'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
fullname = Column(String)
fullname2 = Column(String)
nickname = Column(String)
def __repr__(self):
return "<User(name='%s', fullname='%s', nickname='%s')>" % (
self.name, self.fullname, self.nickname)
# app/tool/__init__.py
from app.tool.tool_entity import Tool
# app/app.py
from flask import Flask
from sqlalchemy import create_engine
from app.tool.tool_routes import tool_blueprint
from app.base import Base
db_dialect = 'postgresql'
db_user = 'postgres'
db_pwd = 'postgrespwd'
db_host = 'db'
db_name = 'db_name'
engine = create_engine(f'{db_dialect}://{db_user}:{db_pwd}@{db_host}/{db_name}', echo=True)
Base.metadata.create_all(engine)
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'hello world'
app.register_blueprint(tool_blueprint, url_prefix='/tool')
if __name__ == '__main__':
# you can add this import here, or anywhere else in the file, as debug (watch mode) is on,
# the table should be created as soon as you save this file.
import app.tool.tool_entity
app.run(host='0.0.0.0', port=5000, debug=True)