我目前有类似的内容(取自SQLAlchemy documentation):
class Employee(Base):
__tablename__ = 'employee'
id = Column(Integer, primary_key=True)
name = Column(String(50))
type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity':'employee',
'polymorphic_on':type
}
class Engineer(Employee):
__tablename__ = 'engineer'
id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
engineer_name = Column(String(30))
__mapper_args__ = {
'polymorphic_identity':'engineer',
}
class Manager(Employee):
__tablename__ = 'manager'
id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
manager_name = Column(String(30))
__mapper_args__ = {
'polymorphic_identity':'manager',
}
使用WhooshAlchemy,我想分别搜索name
列,engineer_name
和manager_name
分别为Engineer
和Manager
。
我已尝试将包含其列的单独__searchable__
列表放入每个类中,但这会给我以下错误:
whoosh.fields.UnknownFieldError: No field named 'name' in <Schema: ['id', 'engineer_name']>
我还尝试将__searchable__
列表放入每个只包含在该特定类中定义的列的列表,但是当我在查询中使用whoosh_search
时,这根本没有给我任何结果,尽管有有效的搜索字词应至少返回1个结果。
最简单的方法是什么?
答案 0 :(得分:0)
您必须明确定义可以处理所有这些模式的模式。 您将覆盖继承类上的可搜索字段。
class Employee(Base):
__tablename__ = 'employee'
__searchable__ = ['name']
id = Column(Integer, primary_key=True)
name = Column(String(50))
type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity':'employee',
'polymorphic_on':type
}
class Engineer(Employee):
__tablename__ = 'engineer'
__searchable__ = ['name', 'engineer_name']
id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
engineer_name = Column(String(30))
__mapper_args__ = {
'polymorphic_identity':'engineer',
}
class Manager(Employee):
__tablename__ = 'manager'
__searchable__ = ['name', 'manager_name ']
id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
manager_name = Column(String(30))
__mapper_args__ = {
'polymorphic_identity':'manager',
}
然后在构建索引时:
from whooshalchemy import IndexService
from whoosh.fields import Schema, TEXT
# However your app initializes it
index_service = IndexService(config=app.config, session=db.session)
my_schema = Schema(name=TEXT, engineer_name=TEXT, manager_name=TEXT)
index = index_service.index_for_model_class(model)
with index.writer() as writer:
for engineer in Engineer.query.all():
index_attrs = {}
for field in Engineer.__searchable__:
index_attrs[field] = str(getattr(engineer, field))
index_attrs["id"] = engineer.id
writer.add_document(**index_attrs)
for manager in Manager.query.all():
index_attrs = {}
for field in Manager.__searchable__:
index_attrs[field] = str(getattr(manager, field))
index_attrs["id"] = manager.id
writer.add_document(**index_attrs)
后来搜索时:
engineer_search_results = Engineer.search_query("SomeText").all()
manager_search_results = Manager.search_query("SomeText").all()
答案 1 :(得分:-2)
如果您也使用烧瓶,您可以尝试我的名为Flask-WhooshAlchemyPlus的flask_whooshalchemy fork,它可以索引继承的模型
您可以为每个模型添加可搜索自己的字段名称
我只需将代码粘贴到此处
def _get_whoosh_schema_and_primary_key(model, analyzer):
schema = {}
primary = None
searchable = set(model.__searchable__)
for field in model.__table__.columns:
if field.primary_key:
schema[field.name] = whoosh.fields.ID(stored=True, unique=True)
primary = field.name
if field.name in searchable and isinstance(field.type,
(sqlalchemy.types.Text,
sqlalchemy.types.String,
sqlalchemy.types.Unicode)):
schema[field.name] = whoosh.fields.TEXT(
analyzer=analyzer, vector=True)
for parent_class in model.__bases__:
if hasattr(parent_class, "_sa_class_manager"):
if parent_class.__searchable__:
for i in set(parent_class.__searchable__):
if hasattr(parent_class, i):
schema[i] = whoosh.fields.TEXT(
analyzer=analyzer, vector=True)
return Schema(**schema), primary