Форум сайта python.su
0
Здравствуйте.
В изучении языка делаю первые шаги и для закрепления прочитанного стараюсь теорию совмещать с практикой, потому поставил себе задачу написать что-то вроде простого географического справочника с рядом функций. К сожалению, недостаток знаний порой препятствует реализации какой-либо идеи, а найти решение проблемы в пособиях или вопросах других пользователей удаётся не всегда, что вынуждает озадачить сообщество своим вопросом.
Подскажите, пожалуйста, как лучше решить следующую задачу:
Есть таблица в базе SQLite, содержащая id элементов, их названия и прочие параметры. Пользователь может создать как базовый элемент (первый уровень), так и дочерний. Все записи носят произвольный характер, количество вложений и их наличие определяет сам пользователь. Существует лишь ограничение на максимальный уровень вложенности, а удаление из базы родительского элемента влечёт за собой удаление и всех входящих в него вложений. То есть, формируемое дерево элементов может выглядеть приблизительно так:
- Европа
- - Беларусь
- - - Витебск
- - Россия
- - - Центральный федеральный округ
- - - - Москва
- - - - Московская область
- - - Южный федеральный округ
- - Украина
- Азия
- Африка
Застрял на реализации логики работы с такими элементами. Лучшее, что пока удалось придумать, так это указывать в базе для каждого элемента его уровень, родителя и дочерние элементы, а потом обрабатывать это в нескольких вложенных циклах. Подозреваю, что существует более грамотное решение, позволяющее работать со связанными между собой элементами, но найти его пока не удалось.
Направьте, пожалуйста, в нужное русло. Интересен не столько сам код, сколько принцип решения задачи с указанием на методы и функции, которые могут быть в этом полезны.
Спасибо.
Отредактировано Rokot (Ноя. 13, 2014 21:10:36)
Офлайн
186
http://www.opennet.ru/docs/RUS/hierarchical_data/
Офлайн
253
На первых порах вполне подойдет система вложенных списков питона и cPickle для сериализации. Если возникнет проблема с объемом данных надежностью хранения или потребуется коллективный доступ с модификацией то тогда можно уже и в базах данных искать? Причем есть специальные базы для таких задачек. http://en.wikipedia.org/wiki/Graph_database
В учебных целях вы легко можете имитировать свою б.д. файловой системой.
Офлайн
0
doza_and
Благодарю за наводку. При написании этой программы преследую не столько исключительно учебные цели, сколько практические - она мне необходима в качестве песочницы, в которой можно разобраться и поэкспериментировать с методами/решениями, которые пригодятся в будущем.
Использовать текстовые файлы (если верно понял Ваши слова про БД системы) не хотелось бы по нескольким причинам: проблемы при изменении структуры записи, невозможность просмотреть все данные сразу, множество мелких файлов вместо одного у SQLite. В своё время, когда довелось немного кодить на PHP + MySQL, в процессе допиливания CMS, работающей на простых файлах, столкнулся со множеством проблем, которых при использовании MySQL или txtSQL не возникало.
P. S. Немного не по теме, но скажу о мотивации. Основной причиной начала изучения Питона была личная заинтересованность в описанной программе. Пролистав несколько страниц поисковой выдачи и покопавшись на нескольких десятках сайтов, нужного мне решения не нашёл. Из нескольких сравниваемых языков выбрал Питон за возможность создания кроссплатформенных приложений и положительные отзывы относительно формирования грамотного стиля написания. Именно поэтому хочу с самого начала сделать качественно и правильно, дабы готовое приложение можно было использовать сразу, постепенно дорабатывая его и дополняя необходимыми функциями.
Офлайн
58
RokotНеа. Не получиться
Именно поэтому хочу с самого начала сделать качественно и правильно
На то оно и начало…
Офлайн
47
для такой задачи достаточно таблицы с полями id, parent_id, name
выгребаешь одним запросом все данные, потом в питоне строишь дерево
по научному это называется Adjacency List
Офлайн
253
Вы неправильно меня поняли.
RokotПосмотрите что я написал. У меня не было слов про текстовый файл. Pickle/cPickle позволяет сохранять объекты питона как в текстовом так и в двоичном виде.
Использовать текстовые файлы
RokotВ деревьях нет понятия записи. Поэтому ваш довод непонятен. Вы имеете ввиду листья?
при изменении структуры записи
RokotНепонятно как вы их вообще хотите смотреть, каким инструментарием, в каком оформлении? Методы просмотра очень слабо связаны со способом хранения данных на диске (по крайней мере для малых объемов данных). Например сделайте dump в yaml файл и смотрите в текстовом редакторе. Чем вас это не устраивает? Это как раз в РСУБД нельзя посмотреть все данные сразу (и лучше такое требование вообще не ставить).
невозможность просмотреть все данные сразу
RokotФайл можно сделать один файл. Почему вы взяли что их будет много? Если делать имитацию в файловой системе то да будет туча. Не нравится не делайте так.
множество мелких файлов
- Европа - Беларусь - Витебск - Россия - Центральный федеральный округ - Москва - Московская область - Южный федеральный округ - Украина - Азия - Африка
import yaml a=yaml.load(open("a.yaml","r"))
Отредактировано doza_and (Ноя. 15, 2014 09:46:04)
Офлайн
0
4kpt_IIНу хоть основа будет, которую дальше можно допилить.
На то оно и начало…

doza_andПрошу извинить, если действительно не понял отсылку к cPickle. Вкупе со словами об имитации своей БД воспринял её в качестве предложения использовать данную функцию в качестве инструмента для записи данных в виде отдельных файлов. Виноват.
У меня не было слов про текстовый файл.
doza_andНе совсем. Деревом данные будут после их вызова из БД, обработки и отрисовки. Имея одну БД со всеми данными могут без особых хлопот добавить в существующую таблицу новый столбец или переименовать существующие. Если же каждая запись будет представлена в виде отдельного файла a-la xml, то просто так все изменить не выйдет.
Вы имеете ввиду листья?
doza_andВ данном случае подразумевал процесс просмотра данных человеком во время разработки. Для SQLite есть неплохие инструменты: Sqliteman, SQlite Designer или SQLite Manager.
Непонятно как вы их вообще хотите смотреть, каким инструментарием, в каком оформлении?
doza_andМолод, зелен, категоричен
Почему вы взяли что их будет много?
. В нескольких найденных решениях, исходный код которых начал ковырять, используется либо SQLite, либо куча папок с текстовыми файлами, вложенных друг в друга. Второй метод мне не приглянулся, несмотря на простоту. С базой, всё же, надёжнее будет. Тем более, уже доводилось работать.doza_andВот это и ищу. То есть, повторюсь, моя задача стоит не в том, как записать дерево, нет. Пытаюсь понять, как лучше обработать имеющиеся в БД данные, чтобы можно было это дерево построить или производить какие-то манипуляции с ветками целиком (переносить на другие уровни, удалять). Может быть, вместо трёх полей level, parent, child можно использовать только parent, а может есть и другие способы.
достаточно загрузить все данные в память поработать а потом все выгрузить
Отредактировано Rokot (Ноя. 15, 2014 18:49:17)
Офлайн
253
Я вам написал что реляционные базы неудобны для деревьев. Вторая строка в ссылке которую вам дали
“реляционные базы не приспособлены к хранению иерархических структур”
Вы ищете способ как загрузить такие данные. Вам дали работающий пример который загружающий именно ваши данные. Что вам еще надо? Зачем вы привязались к этим таблицам? Может у вас уже набиты таблицы?
Отредактировано doza_and (Ноя. 15, 2014 22:43:20)
Офлайн
49
1. Использовать вложенные структуры данных, например словари + pickle для сериализации, возможно использование библиотек для вложенных структур https://pypi.python.org/pypi?%3Aaction=search&term=nested+dict&submit=search
2. Использовать форматы для сериализации и передачи данных: json/bson, xml, yaml.
3. Использовать графовые базы данных, например http://neo4j.com
Офлайн