В настоящее время я следую учебнику 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
а не ошибка, которую мой код по какой-то причине выдает.