SQLAlchemy和Pyramid,如何从上下文中获取资源?

时间:2011-12-08 08:03:32

标签: python sqlalchemy url-routing pyramid

我在Pyramid网络应用程序中缠绕问题。我的结构非常像迈克尔·梅里克尔here描述的结构,除了我使用纯粹的遍历来查找我的观点。 (它们被声明配置为context ='path.toResource'name ='myView'),相当标准的票价根据我可以从traversal wiki tutorial.我可以告诉我的应用程序有一个更复杂的URL结构虽然:我的用户资源是在/users/{user_id}下,我的项目位于/projects/{project_id}下。我的所有资源都使用SQLAlchemy ORM保留;我有一个具有__name____parent__属性的User和Project类,以及扩展列的其他属性。

class User(Base):
    id = Column(...)
    __name__ = None
    __parent__ = None
Class Project(Base):
    id = Column(...)
    __name__ = None
    __parent__ = None
    owner_id = Column(...ForeignKey(User.id))
    owner = relationship(User,...)

我有一个RootFactory,ProjectFactory和UserFactory,用于填充__name__次调用中相应的__parent____get_item__属性。

因此,在Project上下文的视图函数中,我在request.context中获得了一个Project实例。我的问题是如何引用相应的用户实例?我无法执行project.owner,因为该User实例未通过RootFactory链,因此未设置其__parent____name__值。这很糟糕,因为我想使用request.resource_url来查找所有者User的URL,所以我可以在视图页面上放置一个链接。

这里的解决方案是什么?我是否通过request.root 所有?如果我想创建一个返回User或Project实例的复杂查询,该怎么办?是否有某种CrapFactory我可以传递SQLAlchemy所以它的所有实例都能正确填充?

我的做法完全错了吗?

如果我坚持使用URL路由,我觉得我不会遇到这些问题...

1 个答案:

答案 0 :(得分:5)

这是每个人在尝试将SQLAlchemy与遍历混合时遇到的问题。遍历的要求是具有持久的树结构,您可以遍历该结构以从一个节点到另一个节点。

你基本上有两个选择。

  1. 您可以在数据库中构建一个实际树,其中每个资源都知道它所在的位置。因此,当您加载资源时,它可以通过某种方式确定其父级和名称。这是最好的选择。这通常通过在数据库中创建自引用资源表来完成。然后,您的UserProject对象都会有resource_id个外键,可用于确定它们在树中的位置。

  2. 当您从根遍历树时,目前只填充您的姓名和父级,因此您可以通过request.root执行所有操作,以便引用树的其他部分。

  3. 也可以在每个资源上定义一个__resource_url__属性,但对于大多数情况来说这也是相当苛刻的。

    要带走的是,与“我的网址具有此结构”并且实际构建可以使用的该结构的持久层次结构存在很大差异。为了处理URL,它非常简单,但是为了生成它们,没有持久树就会很痛苦。