我正在创建的一个小型博客应用程序中实现SQLAlchemy ORM(作为Alchemy的学习练习)。我偶然发现了一些我不确定的东西-我想我知道一种方法,但是要想成为“最佳”方法可能太久了。一个表/对象具有“标题”列。我希望能够由此创建一个子弹类型的字符串。我查看了混合属性,它似乎可以解决问题。
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
title = Column(String)
@hybrid_property
def slug(self):
return self.title.replace(" ", "-").lower()
def __repr__(self):
return "<Post(id='%s', title='%s', slug='%s')>" % (
self.id, self.title, self.slug)
post = Post(title="Hello World")
session.add(post)
session.commit()
Run Code Online (Sandbox Code Playgroud)
这对于检索值很有效:
>>> p = session.query(Post).filter(Post.title=='Hello World')
>>> p
>>> <Post(id='1', title='Hello World', slug='hello-world')>
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在此属性上使用过滤器时:
>>> p = session.query(Post).filter(Post.slug=='hello-world')
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
>>> File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/attributes.py", line 270, in __ge
tattr__
key)
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with
Post.title has an attribute 'replace'
Run Code Online (Sandbox Code Playgroud)
这是否意味着我应该创建一个自定义比较器?似乎需要做很多工作,因为大多数sql中只有一行。基本上,我的整个方法是否有缺陷?
小智 5
from sqlalchemy import func
...
class Post(Base):
...
@hybrid_property
def slug(self):
return self.title.replace(" ", "-").lower()
@slug.expression
def slug(cls):
return func.lower(func.replace(cls.title, " ", "-"))
...
Run Code Online (Sandbox Code Playgroud)
SQLAlchemy无法理解hybrid_property装饰的函数中的Python代码,因此无法将其转换为本地SQL查询。这就是为什么您需要以某种方式提供它,使得SQLAlchemy可以理解它,就像在expression属性中定义的那样,该SQLAlchemy可以将其转换为SQL查询。
| 归档时间: |
|
| 查看次数: |
1384 次 |
| 最近记录: |