Как проверить и написать в Postgres с помощью Python и Sqlalchemy - PullRequest
0 голосов
/ 05 февраля 2019

Я пишу скребок со скрапом, sqlalchemy и postgres.Я хотел бы, чтобы скрипт проверял наличие новых элементов и, если они есть, отправлял письмо и записывал в базу данных.Я подумал о двух таблицах - одна постоянная и одна временная, отброшенная после обработки данных.Я хотел бы проверить, существуют ли элементы во временном списке в постоянном списке, и если нет - записать их в постоянный список.Как создать выражение, чтобы проверить, существуют ли результаты в другой таблице с помощью sqlalchemy?Я могу успешно записать в обе таблицы, но я борюсь со следующим этапом - проверить наличие изменений и записать новые элементы в постоянную таблицу.

Вот модель для таблицы:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.engine.url import URL
from . import settings
from random import randint

DeclarativeBase = declarative_base()

def db_connect():
    """
    Performs database connection using database settings from settings.py.
    Returns sqlalchemy engine instance
    """
    return create_engine(URL(**settings.DATABASE))

def create_item_table(engine):
    """"""
    DeclarativeBase.metadata.create_all(engine)


class ItemsTemplateTable(object):
    def uid(self):
        return randint(100, 999999999)
    """Sqlalchemy items table model"""
    uid = Column('uid',Integer, default=uid, primary_key=True, unique=True)
    item_name = Column('id', String)
    item_size = Column('title', String)
    item_prize = Column('url', String, nullable=True)

class Items(ItemsTemplateTable, DeclarativeBase):
    __tablename__ = "items"

class AllItems(ItemsTemplateTable, DeclarativeBase):
    __tablename__ = "allitems"

Вот трубопровод

from sqlalchemy.orm import sessionmaker
from sqlalchemy import literal, select, text, exists
from sqlalchemy.sql import exists
from .models import Items, db_connect, create_items_table
from .items import ItemssItem

class ItemsPipeline(object):
    '''Pipeline for storing data from scraped items into a database'''
    def __init__(self):
        '''
        Initialises connection with the database
        Creates a table.
        '''
        engine = db_connect()
        create_items_table(engine)
        self.Session = sessionmaker(bind=engine)

    def process_item(self, item, spider):
        session = self.Session()
        list = Items(**item)
        try:
            session.add(list)
            session.commit()

        except:
            session.rollback()
            raise
        finally:
            session.close()
        return list

1 Ответ

0 голосов
/ 08 февраля 2019

Я думаю, что вместо того, чтобы работать с двумя разными таблицами, я объявлю уникальный индекс (ограничение), охватывающий несколько столбцов, в случае, если вы считаете, что два элемента равны, если tuple (title, url) равны, тогда объявляйте уникальностьограничить оба (название, URL).Вы можете просто вставить значения в основную таблицу, и когда вы попытаетесь сохранить дублирующийся элемент, postgres сгенерирует исключение - IntegrityException в SqlAlchemy.Поймай это исключение и проигнорируй его.Что-то по линии [3].

Пожалуйста, помните, что IntegrityException является своего рода ловушкой для всех.

Пожалуйста, смотрите:

[1] https://www.postgresql.org/docs/9.0/indexes-unique.html

[2] https://docs.sqlalchemy.org/en/latest/core/constraints.html#unique-constraint

[3] Что такое хороший подходпроверить наличие уникальных значений в таблице базы данных с помощью SqlAlchemy в python2.7

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...