[python] 파일 간 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  = 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.pyfrom 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)


답변