БАГРЕПОРТ. Ошибка при добавлении книги
8 years 3 months ago - 8 years 3 months ago #749
by s.v.d.
s.v.d. created the topic: БАГРЕПОРТ. Ошибка при добавлении книги
Натравил каталогизатор на архивы флибусты. Большую часть архивов он признал бэдовыми, т.к. не смог зачитать из них часть книг
ориентируясь на эту тему попробовал поотлаживать
www.sopds.ru/index.php/forum/razdel-pred...-na-nas?limitstart=0
И в-итоге выяснилось, что книги не добавляются тупо потому, что некоторые поля у них слишком длинные и не влезают в базу.
Кусок лога:
Debian jessy, python 3.4, mysql 5.6 Возможно, стоит добавить проверку длины вставляемой строки, и если она превышает максимально допустимую, тупо забирать из неё только первые n символов?
ориентируясь на эту тему попробовал поотлаживать
www.sopds.ru/index.php/forum/razdel-pred...-na-nas?limitstart=0
И в-итоге выяснилось, что книги не добавляются тупо потому, что некоторые поля у них слишком длинные и не влезают в базу.
Кусок лога:
Warning: Spoiler!
[ Click to expand ]
[ Click to hide ]
2016-10-12 18:14:15,102 DEBUG Book fb2-400000-405999.zip/401600.fb2 Added ok.
Traceback (most recent call last):
File "./py/sopdsd.py", line 338, in <module>
daemon.start()
File "./py/sopdsd.py", line 292, in start
Daemon.start(self)
File "./py/sopdsd.py", line 146, in start
self.run()
File "./py/sopdsd.py", line 327, in run
self.run_scanner()
File "./py/sopdsd.py", line 318, in run_scanner
self.scanner.scan_all()
File "/opt/sopds/py/sopdscan.py", line 88, in scan_all
self.processzip(name,full_path,file)
File "/opt/sopds/py/sopdscan.py", line 119, in processzip
self.processfile(n,file,z.open(n),1,file_size,cat_id=cat_id)
File "/opt/sopds/py/sopdscan.py", line 190, in processfile
ser_id=self.opdsdb.addseries(ser_name.strip())
File "/opt/sopds/py/sopdsdb.py", line 300, in addseries
cursor.execute(sql,data)
File "/usr/lib/python3/dist-packages/mysql/connector/cursor.py", line 551, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/usr/lib/python3/dist-packages/mysql/connector/connection.py", line 490, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/usr/lib/python3/dist-packages/mysql/connector/connection.py", line 395, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.DataError: 1406 (22001): Data too long for column 'ser' a t row 1
2016-10-12 18:14:15,167 INFO sopdsDaemon delpid()...
Debian jessy, python 3.4, mysql 5.6 Возможно, стоит добавить проверку длины вставляемой строки, и если она превышает максимально допустимую, тупо забирать из неё только первые n символов?
Last Edit: 8 years 3 months ago by s.v.d..
Please Войти or Create an account to join the conversation.
- s.v.d.
-
Topic Author
- Offline
- Новый участник
-
Less
More
- Posts: 2
8 years 3 months ago - 8 years 3 months ago #752
by s.v.d.
s.v.d. replied the topic: БАГРЕПОРТ. Ошибка при добавлении книги
Кажется понял, в чём дело. Когда попытался пересоздать базу - посыпалась туча ошибок. Базу изначально создавал под mysql5.5, в 5.6 очевидно многое поменялось.
В-общем, так или иначе переделал tables.sql чтоб нормально работало под mysql5.6
Финишный апдейт. Проиндексировались все архивы либрусека. Не прошли только несколько книг, которые имет в названии или аннотации символы, кодирущиеся 4 битами или те, которые скрипт не смог распарсить.
В-общем, так или иначе переделал tables.sql чтоб нормально работало под mysql5.6
Warning: Spoiler!
[ Click to expand ]
[ Click to hide ]
SET NAMES 'utf8';
SET CHARACTER SET utf8;
set global innodb_file_format = BARRACUDA;
set global innodb_large_prefix = ON;
drop table if exists books;
create table books (
book_id INT not null AUTO_INCREMENT,
filename VARCHAR(255),
path VARCHAR(1024),
filesize INT not null DEFAULT 0,
format VARCHAR(8),
cat_id INT not null,
cat_type INT not null DEFAULT 0,
registerdate TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP,
docdate VARCHAR(50),
favorite INT not null DEFAULT 0,
lang VARCHAR(16),
title VARCHAR(255),
annotation VARCHAR(10000),
cover VARCHAR(32),
cover_type VARCHAR(32),
doublicat INT not null DEFAULT 0,
avail INT not null DEFAULT 0,
PRIMARY KEY(book_id),
KEY(filename),
KEY(title,format,filesize),
INDEX(path),
INDEX(cat_id),
INDEX(avail,doublicat),
INDEX(registerdate))
ROW_FORMAT=DYNAMIC;
commit;
drop table if exists catalogs;
create table catalogs (
cat_id INT not null AUTO_INCREMENT,
parent_id INT null,
cat_name VARCHAR(64),
path VARCHAR(1024),
cat_type INT not null DEFAULT 0,
PRIMARY KEY(cat_id),
KEY(cat_name,path(255)));
commit;
drop table if exists authors;
create table authors (
author_id INT not null AUTO_INCREMENT,
first_name VARCHAR(255),
last_name VARCHAR(255),
PRIMARY KEY(author_id),
KEY(last_name,first_name));
commit;
drop table if exists bauthors;
create table bauthors (
author_id INT not NULL,
book_id INT not NULL,
PRIMARY KEY(book_id,author_id),
INDEX(author_id));
commit;
drop table if exists genres;
create table genres(
genre_id INT not null AUTO_INCREMENT,
genre VARCHAR(64),
section VARCHAR(64),
subsection VARCHAR(100),
PRIMARY KEY(genre_id),
KEY(genre));
commit;
drop table if exists bgenres;
create table bgenres(
genre_id INT not NULL,
book_id INT not NULL,
PRIMARY KEY(book_id,genre_id),
INDEX(genre_id));
commit;
drop table if exists series;
create table series(
ser_id INT not null AUTO_INCREMENT,
ser VARCHAR(255),
PRIMARY KEY(ser_id),
KEY(ser));
commit;
drop table if exists bseries;
create table bseries(
ser_id INT not NULL,
book_id INT not NULL,
ser_no TINYINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY(book_id,ser_id),
INDEX(ser_id));
commit;
drop table if exists bookshelf;
create table bookshelf(
user VARCHAR(32) not NULL,
book_id INT not NULL,
readtime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX(user,readtime));
commit;
drop table if exists dbver;
create table dbver(
ver varchar(5));
commit;
insert into dbver(ver) values("0.21");
commit;
insert into authors(author_id,last_name,first_name) values(1,"Неизвестный Автор","");
commit;
DROP PROCEDURE IF EXISTS sp_update_dbl;
DROP PROCEDURE IF EXISTS sp_newinfo;
DROP FUNCTION IF EXISTS BOOK_CMPSTR;
DROP PROCEDURE IF EXISTS sp_mark_dbl;
DELIMITER //
CREATE FUNCTION BOOK_CMPSTR(id INT, cmp_type INT)
RETURNS VARCHAR(1024)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE T VARCHAR(255);
DECLARE fmt VARCHAR(8) DEFAULT '';
DECLARE fsize INT DEFAULT 0;
DECLARE AUTHORS VARCHAR(1024) DEFAULT '';
DECLARE RESULT VARCHAR(1024);
SELECT GROUP_CONCAT(DISTINCT author_id order by author_id SEPARATOR ':') into AUTHORS from bauthors where book_id=id;
IF AUTHORS=NULL THEN
SET AUTHORS='';
END IF;
SELECT UPPER(trim(REPLACE(title,' ',''))),format,filesize INTO T,fmt,fsize FROM books WHERE book_id=id;
IF T=NULL THEN
SET T='';
END IF;
IF cmp_type=1 THEN
SET RESULT=CONCAT_WS(':',T,AUTHORS);
ELSEIF cmp_type=2 THEN
SET RESULT=CONCAT_WS(':',T,fsize,fmt);
ELSE
SET RESULT='';
END IF;
RETURN RESULT;
END //
CREATE PROCEDURE sp_mark_dbl(cmp_type INT)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE idx,prev,current,orig_id INT;
DECLARE ids VARCHAR(512);
DECLARE cur CURSOR for select GROUP_CONCAT(DISTINCT book_id order by filesize DESC SEPARATOR ':') as ids
from books where avail<>0 group by BOOK_CMPSTR(book_id,cmp_type) having SUM(IF(doublicat=0,1,0))<>1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
IF cmp_type=1 or cmp_type=2 THEN
OPEN cur;
WHILE done=0 DO
FETCH cur INTO ids;
IF done=0 THEN
set idx=0;
set prev=-1;
set current=0;
set orig_id=0;
WHILE prev<>current DO
set prev=current;
set idx=idx+1;
SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(ids,':',idx),':',-1) as UNSIGNED) into current;
IF prev<>current THEN
UPDATE books SET doublicat=orig_id where book_id=current;
if orig_id=0 THEN SET orig_id=current; END IF;
END IF;
END WHILE;
END IF;
END WHILE;
CLOSE cur;
END IF;
IF cmp_type=3 THEN
UPDATE books SET doublicat=0;
END IF;
END //
CREATE PROCEDURE sp_newinfo(period INT)
BEGIN
DECLARE min_book_id INT;
select MIN(book_id) into min_book_id from books where registerdate>now()-INTERVAL period DAY;
select 1 s, count(*) from books where book_id>=min_book_id and avail!=0 and doublicat=0
union all
select 2 s, count(*) from (select author_id from bauthors where book_id>=min_book_id group by author_id) a
union all
select 3 s, count(*) from (select genre_id from bgenres where book_id>=min_book_id group by genre_id) a
union all
select 4 s, count(*) from (select ser_id from bseries where book_id>=min_book_id group by ser_id) a
order by s;
END //
DELIMITER ;
commit;
Финишный апдейт. Проиндексировались все архивы либрусека. Не прошли только несколько книг, которые имет в названии или аннотации символы, кодирущиеся 4 битами или те, которые скрипт не смог распарсить.
Last Edit: 8 years 3 months ago by s.v.d..
Please Войти or Create an account to join the conversation.
- s.v.d.
-
Topic Author
- Offline
- Новый участник
-
Less
More
- Posts: 2
Time to create page: 0.084 seconds