Нужно реализовать хранение текстов, но не одних строк, а параграфов текста. К примеру есть стишок:
"""
О великий текст,
Какой величины ты бы ни был
Сохранить тебя мне нужно..
"""
его нужно полностью сохранить с возможность прочтения и изменения (просто изменения старого текста на новый, или удаление старого и добавления нового с таким же "индексом"), соответственно нужна возможность добавления нового текста в (допустим) датабазу, файл или еще куда-то и удаления.
Вариант хранения текста в переменных python отпадает так как их нужно сохранять. Я пробовал (и хочу) реализовать в json, но быстро понял что скорее всего не эффективно сохранять по одной строке из текста и пришел сюда (количество символов в "одной переменной" обычно не превышает 4 тысяч).
Подскажите какой способ сохранения текста можно использовать.
База данных выглядит подходящим вариантом. Сможете хранить полностью свои тексты и обращаться к ним в любом нужном порядке. Даже простой встроенный в python sqlite подойдет, если не планируется совместный доступ к данным.
В json тоже можно, но менее эффективно, т.к. каждый раз его придется полностью считывать, да и хранить большие объемы текста не совсем его предназначение.
Спасибо! Всё работает. Вот образец кода, что я сделал:
supertext = """О великий текст,
Какой величины ты бы ни был
Сохранить тебя мне нужно.."""
cursor.execute("""CREATE TABLE IF NOT EXISTS table1(
id INT,
embed VARCHAR
)""")
if cursor.execute("SELECT id FROM table1 WHERE id = 1").fetchone() is None:
cursor.execute(f"INSERT INTO table1 VALUES (1, '{supertext}')")
connection.commit()
print(cursor.execute("SELECT embed FROM table1 WHERE id = 1").fetchone()[0])
Могу подметить, что VARCHAR может хранить до 2гб текста.
И могу предположить что обеспечить совместный доступ к данным можно используя асинхронную версию sqlite, но в прочем мне этого пока что не требуется.
P.s. Честно, думал что sqlite не умеет сохранять больше одной строки в одну ячейку. Я ошибался.
Иерокопус Таманский, не надо советовать использование ORM там где оно не нужно, иначе человек, чтобы заварить чайник будет вызывать такси, ехать в соседний город, там покупать чайник, ехать в другой город, там покупать удлинитель, ехать в третий город, там зайти в кафешку и выпить чаю....
Tiubert, для текстового поля можно просто писать тип text, т.к. по сути в sqlite всё к нему сводится.
Для работы с БД лучше сразу научитесь использовать параметризованные запросы с подстановкой данных средствами самой системы (через использование "?") вместо ручного форматирования: https://docs.python.org/3/library/sqlite3.html#sql...
Т.е. вместо
cursor.execute(f"INSERT INTO table1 VALUES (1, '{supertext}')")
Использовать
cursor.execute("INSERT INTO table1 VALUES (?, ?)", (1, supertext))
человек, чтобы заварить чайник будет вызывать такси, ехать в соседний город, там покупать чайник, ехать в другой город, там покупать удлинитель, ехать в третий город, там зайти в кафешку и выпить чаю....
При этом благодаря полиморфизму чайник может быть и не электрическим, а за удлинителем ехать придётся только из-за неправильной реализации неправильно понятых паттернов.
rPman,
использование ORM дает преимущество в том, что работа с СУБД делается, как правило, лучше, чем "на коленке". И есть забота о таких вещах, как защита от SQL инъекций и прочие вещи. В некоторых ORM может использоваться и пул соединений к СУБД.
Другое дело, когда человек сам полез в код ORM, понял как всё реализовано и сделал что-то свое, с учетом опыта уведенного. Но это должно быть оправдано.
Everything_is_not_so_bad, не путаем
защита от sql иньекций это параметризированные запросы, их поддерживает штатно драйвер
пул объединений субд это что? точнее зачем?
единственное, ради чего я бы выбирал на старте какую-либо ORM - это отсутствие привязки к типу базы данных, в большинстве случаев их использование похоже и можно даже почти без телодвижений менять бд типа mysql->sqlite.... в мире php мне нравится pdo наверняка такое же можно найти и для python
защита от sql иньекций это параметризированные запросы, их поддерживает штатно драйвер
Многие забывают об этом или даже не знают.
Так же ORM могут решать проблему N+1 запросов и пр.
пул объединений субд это что? точнее зачем?
ну, это когда тебе в коде не нужно заботиться о том когда открывать и открывать соединение к СУБД, а пул соединений делает это за тебя, причем оптимальнее. Потому что если забыл в коде закрыть соединение без пула соединений, то в какой-то момент СУБД откажет в запросах.
Everything_is_not_so_bad, из какого вы года?
если речь идет о том что при использовании веб бакэнда, где на каждый запрос нужно делать новое подключение к базе данных, то это давно поддерживается веб сервером (точнее плагином выбранногй технологии) но да если вы сами что то изобретаете, то почему нет
хранить где то пул подключений это на столько мизерная и простая задача, что любой программист ее решит за десятки минут, без использования фреймворков.
Возможно мы о разных вещах говорим но ORM это когда твой класс - описание твоих объектов автоматически (или на основе какого то описания на своем птичьем языке или в виде кода) связывается с данными в базе данных, либо синтаксически это сделано очень просто. Т.е. ты описываешь класс, его поля, а ORM твои поля автоматом заполняет из базы одним вызовом. На самом деле это очень удобно, когда за тебя автоматически заполняют поля классов, избавляя от написания скучного кода вида this.name=row['name']... и так для 100500 полей, или удобно, когда в объект одной строчкой подгружаются все связанные с ним 1-ко-многие данные ну и отслеживается их изменения. Плюс многие зачем то добавляют в фреймворк функционал самого построения запроса, делая что то типа ->where ->addWhere ->addParameter, я вообще это считаю форменным извращением.
o5a, (насчет подстановки данных с помощью "?") я не заметил в моём случае разницы между подстановкой данных и более мне привычными f-строками.
Насчет primary key я почитал в документации, я понял его "задачу" - каждая строка имеет свой уникальный идентификатор, но не до конца понял "а почему я так не могу?". После добавления primary key в таблицу добавляется просто еще одно правило которое (возможно) никак не сказывается на, например, поиске строки с указанным id: как было WHERE id = 1 так и осталось.
Я еще не тестировал и не видел, что будет если я захочу создать новую строку в таблице с уже существующий id, но предположу и даже могу сказать знаю что без использования primary key строка спокойно создаться, а при использовании primary key выкинет какую-то ошибку. А так как я намерен все равно проверять наличие id перед добавлением новой строки в таблице, не вижу смысла в его использовании. Но если будет смысл, я добавлю его.
Я не так уж и удивился. Моё не знание было только в хранении текста более чем в одной строке.
Из вашего спора, мнения о использовании ORM в качестве субд для хранения текста с идентификатором с помощью питона для человека которому нужно лишь 3 задача: "сохранить, получить, удалить" разделились.
Проблем с безопасностью при использовании sqlite у меня не случится, так как программа работает на локали. Предоставление данных в виде таблиц и ячеек меня вполне устраивает, точно так же как и sql-код. Ещё я увидел про упоминание проблемы N+1 при использовании sqlite, но я подобны не страдаю, все данные запрашиваются за 1 запрос. Если возникнут проблему с асинхронным запросом к ДБ я могу попробовать aiosqlite или перейти на другую ДБ подобного образа - postgresql.
Не смотря на это, например, peewee мне понравился, но реализовывать через классы мне не очень хочется, а ведь это одна из главных задумок ORM. Мне удобнее использовать sqlite, но я не отрицаю того факта что ORM будет безопаснее и практичнее.
(насчет подстановки данных с помощью "?") я не заметил в моём случае разницы между подстановкой данных и более мне привычными f-строками.
Разница в том, что 1) метод подстановки через форматирование небезопасен (если не делать доп. проверки, можно вот так подставить пришедший код на SQL, который исполнится) 2) с ним потребуется дополнительное форматирование данных, если захотите вставить скажем текст с кавычками, или еще какими спецсимволами.
В случае с подстановкой данных можно использовать executemany, чтобы сразу организовать вставку нескольких записей.
Насчет primary key я почитал в документации, я понял его "задачу" - каждая строка имеет свой уникальный идентификатор, но не до конца понял "а почему я так не могу?". После добавления primary key в таблицу добавляется просто еще одно правило которое (возможно) никак не сказывается на, например, поиске строки с указанным id: как было WHERE id = 1 так и осталось.
primary key (PK) нужен как раз для того, чтобы не задавать эти идентификаторы вручную.
Т.е. вместо того, чтобы самому следить за уникальностью id при вставках вида
cursor.execute("INSERT INTO table1(id, embed) VALUES (?, ?)", (1, supertext))
Поле id заводится как primary key и вставка делается без явного задания этого поля, оно автоматически будет инкрементироваться
cursor.execute("INSERT INTO table1(embed) VALUES (?)", (supertext, ))
Но нужно понимать, для чего у вас это поле id. Если это просто уникальная позиция записи в таблице, то лучше и использовать автоматическую генерацию PK. Если же вы хотите его вести как некий однозначный код, когда знаете, что под кодом 1 у вас всегда "О великий текст, ....", под кодом 2 другой определенный текст и т.д., то автоинкремент для данного поля уже не нужен. Но даже в этом случае лучше развязать между собой сущности: PK автоматический инкремент отдельно (то поле id), код отдельно (назначаемый явно вручную). Это будет лучше, если потом захотите связывать эту таблицу с другими по ключам. Но если планируется все проще, скажем это будет просто одна таблица без лишних связей, то можно и не усложнять.
я не заметил в моём случае разницы между подстановкой данных и более мне привычными f-строками.
а вы
На самом деле это очень удобно, когда за тебя автоматически заполняют поля классов, избавляя от написания скучного кода вида this.name=row['name']...
И
мизерная и простая задача, что любой программист ее решит за десятки минут, без использования фреймворков.
(не факт)
Tiubert,
Да я не настаиваю насчёт ORM. Кому-то нравится видеть чистый SQL, а кому-то идиоматический код на Питоне. Начиная с некоторого количества кода стоит взвесить переход на ORM, который, конечно же, не является серебрянной пулей.