如何通过另一个 table(多个 tables)的命令从 MySQL table 管道中保存 Scrapy 项目?
How to save Scrapy items from pipeline in MySQL table by order from another table (multiple tables)?
这是我在 Whosebug 中的第一个问题。 :P 一切正常,除了爬网顺序,我添加了一个优先级方法但没有正常工作。需要先写入所有作者数据,然后写入所有专辑和歌曲数据,并以此顺序存储到数据库中。我想按顺序从另一个项目中查询 MySql table 中的项目。
数据库结构:https://i.postimg.cc/GhF4w32x/db.jpg
示例:首先在 Author table 中写入所有作者项目,然后通过作者 table 的 authorId 在 Album table 中订购专辑项目。
Github 存储库:https://github.com/markostalma/discogs/tree/master/discogs
P.S。我有一个三项 class 用于作者、专辑和歌曲解析器。
我还尝试制作另一个 spider flow 并将所有内容放在一个项目中 class,但没有成功。订单是一样的。 :(
抱歉我的英语不好。
您需要为此设置项目管道。我建议使用 SQL Alchemy 构建 SQL 项目并连接到数据库。您是 SQL Alchemy class 将反映您在数据库模式中拥有的所有 table 关系。让我演示给你看。这是一个类似管道的工作示例,除了您将在 SQLAlchemy 上设置 class 以包含您需要的 m2m 或外键关系。你必须参考他们的 documentation [1] .
一个更加pythonic的方法是保持你的SQL炼金术class和物品名称相同,并做一些像for k,v in item.items() :
这样你就可以循环项目并设置那里的内容。代码很长,但出于某种目的违反了 DRY。
# -*- coding: utf-8 -*-
from scrapy.exceptions import DropItem
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, Boolean, Sequence, Date, Text
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
import datetime
DeclarativeBase = declarative_base()
def db_connect():
"""
This function connections to the database. Tables will automatically be created if they do not exist.
See __tablename__ under RateMds class
MySQL example: engine = create_engine('mysql://scott:tiger@localhost/foo')
"""
return create_engine('sqlite:///reviews.sqlite', echo=True)
class GoogleReviewItem(DeclarativeBase):
__tablename__ = 'google_review_item'
pk = Column('pk', String, primary_key=True)
query = Column('query', String(500))
entity_name = Column('entity_name', String(500))
user = Column('user', String(500))
review_score = Column('review_score', Integer)
description = Column('description', String(5000))
top_words = Column('top_words', String(10000), nullable=True)
bigrams = Column('bigrams', String(10000), nullable=True)
trigrams = Column('trigrams', String(10000), nullable=True)
google_average = Column('google_average', Integer)
total_reviews = Column('total_reviews', Integer)
review_date = Column('review_date', DateTime)
created_on = Column('created_on', DateTime, default=datetime.datetime.now)
engine = db_connect()
Session = sessionmaker(bind=engine)
def create_individual_table(engine):
# checks for tables existance and creates them if they do not already exist
DeclarativeBase.metadata.create_all(engine)
create_individual_table(engine)
session = Session()
def get_row_by_pk(pk, model):
review = session.query(model).get(pk)
return review
class GooglePipeline(object):
def process_item(self, item, spider):
review = get_row_by_pk(item['pk'], GoogleReviewItem)
if review is None:
googlesite = GoogleReviewItem(
query=item['query'],
google_title=item['google_title'],
review_score=item['review_score'],
review_count=item['review_count'],
website=item['website'],
website_type=item['website_type'],
top_words=item['top_words'],
bigrams=item['bigrams'],
trigrams=item['trigrams'],
text=item['text'],
date=item['date']
)
session.add(googlesite)
session.commit()
return item
else:
raise DropItem()
[1]: https://docs.sqlalchemy.org/en/13/core/constraints.html
这是我在 Whosebug 中的第一个问题。 :P 一切正常,除了爬网顺序,我添加了一个优先级方法但没有正常工作。需要先写入所有作者数据,然后写入所有专辑和歌曲数据,并以此顺序存储到数据库中。我想按顺序从另一个项目中查询 MySql table 中的项目。
数据库结构:https://i.postimg.cc/GhF4w32x/db.jpg
示例:首先在 Author table 中写入所有作者项目,然后通过作者 table 的 authorId 在 Album table 中订购专辑项目。
Github 存储库:https://github.com/markostalma/discogs/tree/master/discogs
P.S。我有一个三项 class 用于作者、专辑和歌曲解析器。
我还尝试制作另一个 spider flow 并将所有内容放在一个项目中 class,但没有成功。订单是一样的。 :(
抱歉我的英语不好。
您需要为此设置项目管道。我建议使用 SQL Alchemy 构建 SQL 项目并连接到数据库。您是 SQL Alchemy class 将反映您在数据库模式中拥有的所有 table 关系。让我演示给你看。这是一个类似管道的工作示例,除了您将在 SQLAlchemy 上设置 class 以包含您需要的 m2m 或外键关系。你必须参考他们的 documentation [1] .
一个更加pythonic的方法是保持你的SQL炼金术class和物品名称相同,并做一些像for k,v in item.items() : 这样你就可以循环项目并设置那里的内容。代码很长,但出于某种目的违反了 DRY。
# -*- coding: utf-8 -*-
from scrapy.exceptions import DropItem
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, Boolean, Sequence, Date, Text
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
import datetime
DeclarativeBase = declarative_base()
def db_connect():
"""
This function connections to the database. Tables will automatically be created if they do not exist.
See __tablename__ under RateMds class
MySQL example: engine = create_engine('mysql://scott:tiger@localhost/foo')
"""
return create_engine('sqlite:///reviews.sqlite', echo=True)
class GoogleReviewItem(DeclarativeBase):
__tablename__ = 'google_review_item'
pk = Column('pk', String, primary_key=True)
query = Column('query', String(500))
entity_name = Column('entity_name', String(500))
user = Column('user', String(500))
review_score = Column('review_score', Integer)
description = Column('description', String(5000))
top_words = Column('top_words', String(10000), nullable=True)
bigrams = Column('bigrams', String(10000), nullable=True)
trigrams = Column('trigrams', String(10000), nullable=True)
google_average = Column('google_average', Integer)
total_reviews = Column('total_reviews', Integer)
review_date = Column('review_date', DateTime)
created_on = Column('created_on', DateTime, default=datetime.datetime.now)
engine = db_connect()
Session = sessionmaker(bind=engine)
def create_individual_table(engine):
# checks for tables existance and creates them if they do not already exist
DeclarativeBase.metadata.create_all(engine)
create_individual_table(engine)
session = Session()
def get_row_by_pk(pk, model):
review = session.query(model).get(pk)
return review
class GooglePipeline(object):
def process_item(self, item, spider):
review = get_row_by_pk(item['pk'], GoogleReviewItem)
if review is None:
googlesite = GoogleReviewItem(
query=item['query'],
google_title=item['google_title'],
review_score=item['review_score'],
review_count=item['review_count'],
website=item['website'],
website_type=item['website_type'],
top_words=item['top_words'],
bigrams=item['bigrams'],
trigrams=item['trigrams'],
text=item['text'],
date=item['date']
)
session.add(googlesite)
session.commit()
return item
else:
raise DropItem()
[1]: https://docs.sqlalchemy.org/en/13/core/constraints.html