【发布时间】:2013-11-20 23:10:19
【问题描述】:
我有一个具有父子关系的类:
Base = declarative_base()
class Parent(Base):
__tablename__ = "parent_table"
id = Column(Integer, primary_key=True)
children = relationship("Child", backref="parent")
def all_children(self):
pass # I want self.children + "Child where parent_id = NULL"
class Child(Base):
__tablename__ = "child_table"
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent_table.id')
我想向我的父级添加一个函数,它返回关系中父级的子级,以及所有将 parent_id 列设置为 NULL 的子级对象。
整个情况有点复杂,因为类实际上是这样的连接表继承的情况:table_per_related,但我什至不知道从哪里开始,所以可能可以从那里弄清楚.
(整个东西必须可以通过 Flask 在 Web 服务的上下文中使用)
编辑:更新。这是我真正想做的最小实现,因为我无法将第一个答案翻译成在这种情况下有效的东西:
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
class BaseCols:
id = Column(Integer, primary_key=True)
name = Column(String)
def __repr__(self):
return "<{}: {} - {}>".format(self.__class__.__name__, self.id, self.name)
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
Base = declarative_base(cls=BaseCols)
class Child(BaseCols):
pass
class HasChild:
@declared_attr
def children(cls):
cls.Child = type("{}Child".format(cls.__name__),
(Child, Base,),
dict(
__tablename__="{}_children".format(cls.__tablename__),
parent_id=Column(Integer, ForeignKey("{}.id".format(cls.__tablename__))),
parent=relationship(cls)
)
)
return relationship(cls.Child)
def all_children(self):
pass
class Foo(Base, HasChild):
__tablename__ = 'foo'
__mapper_args__ = {'concrete': True}
class Bar(Base, HasChild):
__tablename__ = 'bar'
__mapper_args__ = {'concrete': True}
if __name__ == "__main__":
engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)
session = Session(engine)
session.add_all([
Foo(
name = "Foo the first!",
children = [
Foo.Child(name="Heir Apparent."),
Foo.Child(name="Spare.")
]
),
Foo(
name = "Foo the second...",
children = [
Foo.Child(name="Some child."),
]
),
Bar(
name = "Bar the first!",
children = [
Bar.Child(name="Bar's.")
]
),
Foo.Child(name="whoops"),
])
session.commit()
foo1 = session.query(Foo).first()
print(foo1)
print(foo1.children)
print(foo1.all_children(session))
【问题讨论】:
标签: python sqlalchemy flask