SQLAlchemy импортирует таблицы с отношениями
У меня проблема с разделением таблиц с отношениями в разных файлах. Я хочу, чтобы приведенные ниже таблицы были в трех отдельных файлах и импортировали TableA на стороннюю страницу, но я не могу управлять порядком загрузки.
В большинстве случаев я получаю следующую ошибку.
sqlalchemy.exc. InvalidRequestError: при инициализации mapper Mapper | TableA | tablea, выражение "TableB" не удалось найти имя ( "имя" TableB "не определено" ). Если это класс
name, подумайте о добавлении этого отношения() в класс после определения обоих зависимых классов.
class TableA(Base):
__tablename__ = "tablea"
id = Column(Integer, primary_key=True)
name = Column(String)
tableB = relationship("TableB", secondary = TableC.__table__)
class TableB(Base):
__tablename__ = "tableb"
id = Column(Integer, primary_key=True)
name = Column(String)
class TableC(Base):
__tablename__ = "tableab"
tableAId = Column("table_a_id", Integer, ForeignKey("TableA.id"), primary_key=True)
tableBId = Column("table_b_id", Integer, ForeignKey("TableB.id"), primary_key=True)
Ответы
Ответ 1
Это должно работать (обратите внимание, что таблица Table. заменяется именем таблицы, чтобы избежать загрузки циклического модуля):
### base.py
engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine)
Base = declarative_base(bind=engine)
### classA.py
from base import Base
from classB import TableB
class TableA(Base):
__tablename__ = 'tablea'
id = Column(Integer, primary_key=True)
name = Column(String(50))
tableBs = relationship("TableB", secondary="tableab")
#tableBs = relationship("TableB", secondary=TableC.__table__)
### classB.py
from base import Base
class TableB(Base):
__tablename__ = 'tableb'
id = Column(Integer, primary_key=True)
name = Column(String(50))
### classC.py
from base import Base
from classA import TableA
from classB import TableB
class TableC(Base):
__tablename__ = 'tableab'
tableAId = Column(Integer, ForeignKey("tablea.id"), primary_key=True, )
tableBId = Column(Integer, ForeignKey("tableb.id"), primary_key=True, )
### main.py
from base import Base, Session, engine
from classA import TableA
from classB import TableB
from classC import TableC
Base.metadata.create_all(engine)
Также я считаю, что параметр ForeignKey чувствителен к регистру, поэтому код может не работать, потому что sno файл таблицы "TableA.id" соответствует имени "tablea", когда он чувствителен к регистру.
Ответ 2
from sqlalchemy import Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Parent(Base):
__tablename__ = 'Parent'
ParentID = Column(Integer, primary_key=True)
Description = Column(String)
def __init__(self, ParentID, Description):
self.ParentID = ParentID
self.Description = Description
----------------------------------------------------------------------
from sqlalchemy import Column, String, Integer, ForeignKey
import Parent
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Child(Base):
__tablename__ = "Child"
ChildID = Column(Integer, primary_key=True)
Description = Column(String)
ParentID = Column('CompanyID', Integer, ForeignKey(Parent.ParentID))
def __init__(self, ChildID, Description,ParentID):
self.ChildID = ChildID
self.Description = Description
self.ParentID=ParentID
Ответ 3
Просто измените первую строку для класса ForeignKey и добавьте еще одну для класса отношений, как показано ниже:
from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.orm import relationship
Чтобы отключить предупреждения об изменениях, добавьте еще одну строку
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
Измените имя таблицы 'tableab' на 'tableb', по этой причине она выдает ошибку, так как tableB не найден. Кроме того, Python чувствителен к регистру, и мы должны помнить это.
Надеюсь, этого будет достаточно.