Почему мой код выдает ошибку «Неудачное ограничение UNIQUE: parent_reply.parent_id», а та, за которой я следую, - нет? - PullRequest
0 голосов
/ 02 мая 2019

В настоящее время я следую учебнику sentdex по созданию чат-бота с глубоким обучением с Python и TensorFlow. Он использует набор данных за один месяц комментариев Reddit и базу данных sqlite3.

Моя проблема в том, что всякий раз, когда я пытаюсь запустить свой код, я получаю:
UNIQUE constraint failed: parent_reply.parent_id

Хотя я понимаю, что может вызвать ошибку, я не могу найти причину, по которой исходный код из учебника работает без проблем, а мой - нет (я уже прошел и мой, и его код сверху вниз и не смог найти каких-либо существенных различий).

Я уже пытался изменить SQL-запросы в insert_parent_exists и insert_no_parent методах с INSERT INTO parent_reply на INSERT OR REPLACE и INSERT OR IGNORE, но оба они создают базу данных с False в качестве значения родителя, где это применимо , Я также заметил, что комментирование одного из этих методов в последнем блоке else моего кода приводит к тому, что код запускается без каких-либо ошибок, но не создает парных комментариев (насколько я понимаю, если выполняется только одна из этих функций) PRIMARY KEY не нарушается, поэтому нет ошибок).

Ниже я предоставил мой код и код sentdex (основной цикл сценария и методы, используемые для вставки базы данных).

Мой код:

import json
import sqlite3
from datetime import datetime

path = '/Users/MateuszGrzybek/Desktop/DL-Chatbot/data/RC_2015-01'
db_transaction = []


def db_connect(conn, cursor):
    """Create all the necessary tables."""
    try:
        cursor.execute('DROP TABLE IF EXISTS parent_reply;')
        # create table
        print('Creating tables...')
        cursor.execute(
            """CREATE TABLE IF NOT EXISTS parent_reply (parent_id TEXT PRIMARY
            KEY, comment_id TEXT UNIQUE, parent TEXT, comment TEXT,
            subreddit TEXT, unix INT, score INT);""")
    except Exception as error:
        print(error)
    finally:
        if conn is not None:
            print('Table created.')


def replace_comment(parent_id, comment_id, parent_data, body,
                    subreddit, created_utc, score):
    """Replace a comment if it doesn't fit."""
    try:
        query = """UPDATE parent_reply SET parent_id = '{}', comment_id = '{}',
        parent = '{}', comment = '{}', subreddit = '{}', unix = {},
        score = {} WHERE parent_id = '{}';""".format(parent_id, comment_id,
                                                     parent_data, body,
                                                     subreddit,
                                                     int(created_utc), score,
                                                     parent_id)
        transaction_builder(query)
    except Exception as e:
        print(str(e))


def insert_parent_exists(parent_id, comment_id, parent_data, body, subreddit,
                         created_utc, score):
    try:
        query = """INSERT INTO parent_reply (parent_id, comment_id, 
        parent, comment, subreddit, unix, score) VALUES ('{}', '{}',
        '{}', '{}', '{}', {}, {});""".format(parent_id, comment_id,
                                             parent_data, body, subreddit,
                                             int(created_utc), score)
        transaction_builder(query)
    except Exception as e:
        print(str(e))


def insert_no_parent(parent_id, comment_id, body, subreddit,
                     created_utc, score):
    try:
        query = """INSERT INTO parent_reply (parent_id, comment_id,
        comment, subreddit, unix, score) VALUES ('{}', '{}', '{}', '{}',
        {}, {});""".format(parent_id, comment_id, body, subreddit, int(created_utc),
                           score)
        transaction_builder(query)
    except Exception as e:
        print(str(e))


def transaction_builder(query):
    """Build a database transaction"""
    global db_transaction
    db_transaction.append(query)
    if len(db_transaction) > 1000:
        cursor.execute('BEGIN TRANSACTION;')
        for query in db_transaction:
            try:
                cursor.execute(query)
            except Exception as e:
                print(str(e))
        conn.commit()
        db_transaction = []


if __name__ == "__main__":
    conn = sqlite3.connect('2015-01-1.db')
    cursor = conn.cursor()
    db_connect(conn, cursor)
    row_count = 0
    paired_rows = 0

    with open(path, buffering=1000) as f:
        for row in f:
            row_count += 1
            row = json.loads(row)
            body = format_body(row['body'])
            parent_id = row['parent_id']
            score = row['score']
            subreddit = row['subreddit']
            comment_id = row['name']
            created_utc = row['created_utc']
            parent_data = find_parent(parent_id)

            if score >= 2:
                existing_comment_score = find_existing_score(parent_id)
                if existing_comment_score:
                    if score > existing_comment_score:
                        if acceptable_comment(body):
                            replace_comment(parent_id, comment_id,
                                            parent_data, body, subreddit,
                                            created_utc, score)
                else:
                    if acceptable_comment(body):
                        if parent_data:
                            insert_parent_exists(parent_id, comment_id,
                                                 parent_data, body,
                                                 subreddit, created_utc, score)
                            paired_rows += 1
                        else:
                            insert_no_parent(parent_id, comment_id, body,
                                             subreddit, created_utc, score)

            if row_count % 100000 == 0:
                print('Total rows analyzed: {}\nPaired Rows: {}\nTime: {}'.
                      format(row_count, paired_rows, str(datetime.now())))

Код учебника:

import sqlite3
import json
from datetime import datetime

timeframe = '2015-01'
sql_transaction = []
path = '/Users/MateuszGrzybek/Desktop/DL-Chatbot/data/RC_2015-01'
connection = sqlite3.connect('sent(1).db')
c = connection.cursor()


def create_table():
    c.execute('DROP TABLE IF EXISTS parent_reply;')
    c.execute(
        """CREATE TABLE IF NOT EXISTS parent_reply(parent_id TEXT PRIMARY KEY,
        comment_id TEXT UNIQUE, parent TEXT, comment TEXT, subreddit TEXT,
        unix INT, score INT)""")


def transaction_bldr(sql):
    global sql_transaction
    sql_transaction.append(sql)
    if len(sql_transaction) > 1000:
        c.execute('BEGIN TRANSACTION')
        for s in sql_transaction:
            try:
                c.execute(s)
            except:
                pass
        connection.commit()
        sql_transaction = []


def sql_insert_replace_comment(commentid, parentid, parent, comment, subreddit,
                               time, score):
    try:
        sql = """UPDATE parent_reply SET parent_id = ?, comment_id = ?,
        parent = ?, comment = ?, subreddit = ?, unix = ?, score = ?
        WHERE parent_id = ?;""".format(parentid, commentid, parent, comment,
                                       subreddit, int(time), score, parentid)
        transaction_bldr(sql)
    except Exception as e:
        print('s0 insertion', str(e))


def sql_insert_has_parent(commentid, parentid, parent, comment, subreddit,
                          time, score):
    try:
        sql = """INSERT INTO parent_reply (parent_id, comment_id, parent,
        comment, subreddit, unix, score) VALUES ("{}", "{}", "{}", "{}", "{}",
        {}, {});""".format(parentid, commentid, parent, comment, subreddit,
                           int(time), score)
        transaction_bldr(sql)
    except Exception as e:
        print('s0 insertion', str(e))


def sql_insert_no_parent(commentid, parentid, comment, subreddit, time, score):
    try:
        sql = """INSERT INTO parent_reply (parent_id, comment_id, comment,
        subreddit, unix, score) VALUES ("{}", "{}", "{}", "{}", {}, {});""".format(parentid, commentid, comment, subreddit, int(time), score)
        transaction_bldr(sql)
    except Exception as e:
        print('s0 insertion', str(e))


if __name__ == '__main__':
    create_table()
    row_counter = 0
    paired_rows = 0

    with open(path, buffering=1000) as f:
        for row in f:
            row_counter += 1
            row = json.loads(row)
            parent_id = row['parent_id']
            body = format_data(row['body'])
            created_utc = row['created_utc']
            score = row['score']
            comment_id = row['name']
            subreddit = row['subreddit']
            parent_data = find_parent(parent_id)
            if score >= 2:
                existing_comment_score = find_existing_score(parent_id)
                if existing_comment_score:
                    if score > existing_comment_score:
                        if acceptable(body):
                            sql_insert_replace_comment(comment_id, parent_id,
                                                       parent_data, body,
                                                       subreddit, created_utc,
                                                       score)

                else:
                    if acceptable(body):
                        if parent_data:
                            sql_insert_has_parent(comment_id, parent_id,
                                                  parent_data, body, subreddit,
                                                  created_utc, score)
                            paired_rows += 1
                        else:
                            sql_insert_no_parent(comment_id, parent_id, body,
                                                 subreddit, created_utc, score)

            if row_counter % 100000 == 0:
                print('Total Rows Read: {}, Paired Rows: {}, Time: {}'.format(
                    row_counter, paired_rows, str(datetime.now())))

Я ожидаю, что результат будет последним оператором печати:

Total Rows Read: 100000
Paired Rows: 3718
Time: 2019-05-02 14:43:52.472389

а не ошибка, которую мой код по какой-то причине выдает.

1 Ответ

0 голосов
/ 02 мая 2019

Методом проб и ошибок я обнаружил, что в своем коде он делает:

def transaction_bldr(sql):
    for s in sql_transaction:
        try:
            c.execute(s)
        except:
            pass

, а я делал:

def transaction_builder(query):
    for query in db_transaction:
        try:
            cursor.execute(query)
        except Exception as e:
            print(str(e))

Он просто передал любое исключение, которое могло произойтиво время транзакции sql, таким образом, нет ошибки при запуске его кода.Изменение блока except на pass вызвало еще одну ошибку в моем коде: Incorrect number of bindings supplied. The current statement uses 8, and there are 0 supplied при replace_comment методе.Я исправил это путем изменения полей замены с {} на ?.Хотя я мог бы использовать некоторые уточнения, почему это так важно.

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