SQLAlchemy和Pyramid,如何断章取义资源?
我在理解 Pyramid Web 应用程序时遇到问题。我的结构非常类似于 Michael Merickel 此处 描述的结构,除了我使用纯遍历来查找我的视图。 (它们被声明配置为 context='path.toResource' name='myView'),根据我从 遍历 wiki 教程。 不过,我的应用程序有一个更复杂的 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,它们在其 __get_item__
调用中填充相应的 __name__
和 __parent__
属性。
因此,在 Project 上下文的视图函数中,我在 request.context 中获得了一个 Project 实例。我的问题是我到底如何引用相应的 User 实例?我无法执行project.owner,因为该 User 实例没有经过 RootFactory 链,因此它的 __parent__ 和 __name__ 值未设置。这很糟糕,因为我想使用 request.resource_url 来查找所有者 User 的 URL,这样我就可以在视图页面上放置一个链接。
这里的解决方案是什么?我是否通过 request.root 执行所有操作?如果我想要进行返回用户或项目实例的复杂查询该怎么办?是否有某种我可以传递 SQLAlchemy 的 CrapFactory 以便它的所有实例都能正确填充?
我的方法完全错误吗?
我觉得如果我坚持使用 URL 路由就不会遇到这些问题......
I'm having a problem wrapping my head around my Pyramid web application. I have it structured very much like the one described by Michael Merickel here, except I'm using pure traversal to find my views. (They are declared configured with context='path.toResource' name='myView'), pretty standard fare according to what I can tell from the traversal wiki tutorial. My application has a more complex URL structure though: My User resources are under /users/{user_id}
and my projects are under /projects/{project_id}
. All of my resources are persisted using the SQLAlchemy ORM; I have a User and Project class with __name__
and __parent__
attributes, as well as other attributes extending Columns.
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,...)
I have a RootFactory, ProjectFactory and UserFactory that populate the appropriate __name__
and __parent__
attributes in their __get_item__
calls.
So, in the view functions for the Project context, I get a Project instance in request.context. My issue is how the heck do I reference the corresponding User instance? I can't do project.owner, because that User instance didn't go through the RootFactory chain, so its __parent__
and __name__
values are unset. This is bad, because I want to use request.resource_url to find the URL for the owner User, so I can put a link on the view page.
What's the solution here SO? Do I do everything through request.root? What if I want to make a complex query that returns User or Project instances? Is there some kind of CrapFactory I can pass SQLAlchemy so all its instances get populated properly?
Is my approach just completely wrong?
I feel like I wouldn't be having these kinds of problems if I just stuck with URL Routing...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是每个人在尝试将 SQLAlchemy 与遍历混合时遇到的问题。遍历的要求是拥有一个持久的树结构,您可以遍历该树结构以从一个节点到达另一个节点。
你基本上有两个选择。
您可以在数据库中构建一个实际的树,其中每个资源都知道它所在的位置。因此,当您加载资源时,它可以通过某种方式确定其父资源和名称。这是最好的选择。这通常是通过在数据库中创建自引用资源表来完成的。然后,您的
User
和Project
对象都将具有resource_id
外键,它们可以用来确定它们在树中的位置。当前仅当您从根遍历树时才会填充您的名称和父级,因此您可以通过
request.root
执行所有操作,以便引用树的其他部分。也可以只在每个资源上定义一个 __resource_url__ 属性,但这对于大多数情况来说也是相当黑客的。
需要注意的是,说“我的 url 具有此结构”与实际构建您可以使用的该结构的持久层次结构有很大区别。处理 URL 相当简单,但如果没有持久树,生成 URL 可能会很痛苦。
This is the issue everyone runs into when trying to mix SQLAlchemy with traversal. A requirement of traversal is having a persistent tree structure that you can traverse to get from one node to another.
You basically have 2 options.
You can build an actual tree in your database where each resource knows where it is located. Thus when you load a resource it has some way of determining its parent and name. This is the best option. This is commonly done by creating a self-referential resource table in your database. Then your
User
andProject
objects would both haveresource_id
foreign keys that they could use to determine where they are at within the tree.Your name and parent are currently only populated when you traverse the tree from the root, so you can do everything through
request.root
in order to reference other parts of the tree.It is also possible to just define a
__resource_url__
property on each resource but this is fairly hackish as well for most cases.The thing to take away is that there is a big difference from saying "my urls have this structure" and actually building a persistent hierarchy of that structure that you can use. For handling URLs it's fairly simple, but for generating them it can be painful without a persistent tree.