如何通过另一个 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