Program Tip

파일 간 SQLAlchemy 클래스

programtip 2020. 11. 18. 09:41
반응형

파일 간 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

Python 2.7 + Flask 0.10 + SQLAlchemy 1.0.8 + Postgres 9.4.4.1을 사용하고 있습니다.

이 상용구는 "user"모듈의 동일한 파일 "models.py"에 저장된 User 및 UserDetail 모델로 구성됩니다. 이러한 클래스는 모두 SQLAlchemy 기본 클래스에서 상속됩니다.

All of the additional classes I've added to my project also derived from this base class, and as the models.py file grew larger, I decided to split the models.py file into one file per class, and ran into the problem described here.

The solution I found, along the same lines as @computermacgyver's Oct 23 2013 post, was to include all my classes to the init.py file of the new module I created to hold all the newly created class files. Looks like this:

/project/models/

__init__.py contains

from project.models.a import A 
from project.models.b import B
etc...

If I may add my bit of sense as well since I had the same problem. You need to import the classes in the file where you create the Base = declarative_base() AFTER you created the Base and the Tables. Short example how my project is set up:

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

참고URL : https://stackoverflow.com/questions/7478403/sqlalchemy-classes-across-files

반응형