SQLAlchemy - сопоставление самореферентных отношений как одного для многих (декларативная форма)
Я хочу отобразить сущность Tag с помощью декларативного метода с SQLAlchemy. У тега может быть родитель (другой тег).
Я имею:
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
label = Column(String)
def __init__(self, label, parentTag=None):
self.label = label
Как я могу добавить "родительские" отношения?
Ответы
Ответ 1
Вы добавляете ForeignKey
ссылающийся на родителя, а затем создаете связь, которая указывает направление через remote_side
. Это задокументировано в списке отношений смежности. Для декларативного вы бы сделали что-то вроде этого:
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
label = Column(String)
parent_id = Column(Integer, ForeignKey('tag.id'))
parent = relationship('Tag', remote_side=[id])
Если вы хотите также обратную связь, добавьте backref='children'
к определению отношения.
Ответ 2
Если вам нужны дети, вам нужно использовать uselist
:
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
label = Column(String)
child_id = Column(Integer, ForeignKey('tag.id'))
children = relation('Tag', remote_side=[id], uselist=True)
Ответ 3
parent = relation('Tag')
- см. http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html#configuring-relations.
Ответ 4
Это называется шаблоном списка смежности, который является общим реляционным шаблоном, в котором таблица содержит ссылку на внешний ключ для себя.
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
label = Column(String)
parent_id = Column(Integer, ForeignKey('node.id'))
children = relationship("Tag")
Если вы хотите оба направления, можете использовать:
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
label = Column(String)
parent_id = Column(Integer, ForeignKey('node.id'))
children = relationship("Tag",
backref=backref('parent', remote_side=[id])
)
См. [1]
[1] http://docs.sqlalchemy.org/en/latest/orm/self_referential.html
Ответ 5
class Company(BaseModel):
__tablename__ = 'companies'
companyName = db.Column(db.String(50))
contactPerson = db.Column(db.String(50))
email = db.Column(db.String(50))
mobile = db.Column(db.String(20))
parentID = db.Column(db.Integer, db.ForeignKey('companies.id')) # parent company ID
childrenCompany = db.relationship('Company', remote_side='Company.id',
backref=db.backref('children_company')) # parent Company
Использование:
In [2]: company_query = Company.query.get_or_404(1)
In [3]: company_query.children_company
Out[3]:
[<app.models.user.Company at 0x10f527850>,
<app.models.user.Company at 0x10f527c10>]