我正在使用Scrapy从网络论坛中抓取数据。我使用SQLAlchemy将这些数据存储在PostgreSQL数据库中。表和列创建很好,但是,我无法让SQLAlchemy在其中一列上创建索引。我正在尝试使用gin创建一个三元组索引(pg_trgm)。
创建此索引的Postgresql代码是:
CREATE INDEX description_idx ON table USING gin (description gin_trgm_ops);
我添加到models.py文件中的SQLAlchemy代码是:
desc_idx = Index('description_idx', text("description gin_trgm_ops"), postgresql_using='gin')
我已将此行添加到我的models.py中但是当我检入postgresql时,从未创建索引。
下面是我的完整models.py和pipelines.py文件。我这一切都错了吗?
非常感谢任何帮助!!
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Index, text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.engine.url import URL
import settings
DeclarativeBase = declarative_base()
def db_connect():
return create_engine(URL(**settings.DATABASE))
def create_forum_table(engine):
DeclarativeBase.metadata.create_all(engine)
class forumDB(DeclarativeBase):
__tablename__ = "table"
id = Column(Integer, primary_key=True)
title = Column('title', String)
desc = Column('description', String, nullable=True)
desc_idx = Index('description_idx', text("description gin_trgm_ops"), postgresql_using='gin')
from scrapy.exceptions import DropItem
from sqlalchemy.orm import sessionmaker
from models import forumDB, db_connect, create_forum_table
class ScrapeforumToDB(object):
def __init__(self):
engine = db_connect()
create_forum_table(engine)
self.Session = sessionmaker(bind=engine)
def process_item(self, item, spider):
session = self.Session()
forumitem = forumDB(**item)
try:
session.add(forumitem)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return item
答案 0 :(得分:7)
在SQLAlchemy中引用Operator Class的正确方法(例如> library(stringr)
> ss <- c('jobs?search=term1&location=&distance=10+page=2','jobs?search=term1+term2&location=ca&distance=30','jobs?search=term1+term2+term3&location=nyc&distance=25')
> results <- str_match(ss, "[&?]search=([^&+]+)(?:&|$)")
> results[,2]
[1] "term1" NA NA
>
)是使用gin_trgm_ops
参数。这也可以让alembic等工具了解在自动生成迁移时如何使用它。
postgresql_ops
答案 1 :(得分:5)
由于Index
定义使用text
表达式,因此它没有引用Table
&#34;表&#34;,它已由声明性类{{1}隐式创建}}。相比之下,使用forumDB
作为表达式或其衍生物,如下所示:
Column
在上面的定义中,索引会知道表格,反之亦然。
在您的情况下,这意味着Index('some_index_idx', forumDB.title)
&#34;表&#34;不知道这样的索引存在。将它添加为声明性类的属性是错误的方法。它应该传递给隐式创建的Table
实例。属性__table_args__
仅适用于此:
Table
修改到位后,调用class forumDB(DeclarativeBase):
__tablename__ = "table"
# Note: This used to use `text('description gin_trgm_ops')` instead of the
# `postgresql_ops` parameter, which should be used.
__table_args__ = (
Index('description_idx', "description",
postgresql_ops={"description": "gin_trgm_ops"},
postgresql_using='gin'),
)
id = Column(Integer, primary_key=True)
title = Column('title', String)
desc = Column('description', String, nullable=True)
会导致:
create_forum_table(engine)