Можно ли реализовать список, набор или словарь Python незаметно с помощью базы данных?

Собственные возможности Python для списков, наборов и словарей просто потрясающие. Есть ли способ продолжить использование собственных возможностей, когда объем данных станет действительно большим? Проблема, над которой я работаю, связана с сопоставлением (пересечением) очень больших списков. Я еще не раздвинул пределы — на самом деле я действительно не знаю, каковы пределы — и не хочу удивляться большой повторной реализации после того, как данные вырастут, как ожидалось.

Разумно ли развертывать на чем-то вроде Google App Engine, который не рекламирует никаких практических ограничений по масштабу, и продолжать использовать собственные возможности как есть всегда и не думать об этом?

Есть ли какая-то магия Python, которая может скрыть, находится ли список, набор или словарь в памяти, управляемой Python, или в БД, чтобы физическое развертывание данных можно было отделить от того, что я делаю в коде?

Как вы, г-н или г-жа Python Super Expert, справляетесь со списками, наборами и словарями по мере роста объема данных?


person Chris Johnson    schedule 11.07.2011    source источник
comment
Может быть, вам нужен SQLAlchemy? Или другой ОРМ? И сохранить данные в базу данных?   -  person Denis    schedule 11.07.2011
comment
Мистер и мисс Суперэксперты Python называются питоновцы. ;-)   -  person Aufwind    schedule 11.07.2011
comment
Чрезвычайно сложно, если не невозможно, сериализовать и десериализовать произвольные объекты Python, но легко сохранить подмножество объектов Python, таких как int, str, list и dict, используя pickle/json или что-то еще. Однако постоянство данных составляет лишь небольшую часть вашей проблемы. Еще одна проблема, которую необходимо решить, заключается в том, что вам нужно создать какой-то сопоставитель для сопоставления вашего объекта с базой данных. Если вы используете реляционные базы данных, такие как Postgresql или MySQL, вы можете взглянуть на ORM, такие как Sqlalchemy, но если вы можете использовать только большие таблицы GAE, вам может потребоваться написать свой собственный ORM...   -  person Overmind Jiang    schedule 11.07.2011
comment
@Druss: не официально и никогда не будет. Лично я заклинатель змей.   -  person Chris Morgan    schedule 11.07.2011
comment
@Druss, впервые слышу о заклинателях змей. Звучит тоже аккуратно. ;-)   -  person Aufwind    schedule 11.07.2011
comment
@Druss: я не знаю, чтобы кто-нибудь использовал его, кроме моего отца и меня. И если вы называете себя заклинателем змей, люди могут (возможно) спросить!   -  person Chris Morgan    schedule 11.07.2011
comment
docs.python.org/library/shelve.html   -  person Ignacio Vazquez-Abrams    schedule 12.07.2011


Ответы (3)


Я не совсем понимаю, что вы подразумеваете под нативными возможностями для списков, наборов и словарей. Однако вы можете создавать классы, эмулирующие типы контейнеров и типы последовательностей путем определения некоторых методы со специальными именами. Это означает, что вы можете создать класс, который ведет себя как список, но хранит свои данные в базе данных SQL или в хранилище данных GAE. Проще говоря, это то, что делает ORM. Однако сопоставление объектов с базой данных очень сложно, и, вероятно, лучше не изобретать собственную ORM, а использовать уже существующую.

Боюсь, универсального решения нет. В частности, GAE — это не какая-то волшебная пыльца фей, которой можно посыпать свой код, чтобы он масштабировался. Существует несколько ограничений, которые необходимо учитывать при создании масштабируемого приложения. Некоторые из них являются общими, например сложность вычислений, другие относятся к среде, в которой работает ваш код. Например в GAE максимальное время отклика ограничено 30 секундами, и запрос к хранилищу данных работает иначе, чем в других базах данных.

Трудно дать какой-либо конкретный совет, не зная вашей конкретной проблемы, но я сомневаюсь, что GAE — правильное решение.

В общем, если вы хотите работать с большими наборами данных, вы либо должны помнить об этом с самого начала, либо вам придется перерабатывать свой код, алгоритмы и структуры данных по мере роста наборов данных.

person Daniel Hepper    schedule 11.07.2011
comment
Максимальное время ответа в 30 секунд применяется только к запросам, обращенным к пользователю. Автономные запросы ограничены 10 минутами, а бэкенды не имеют ограничения на выполнение. - person Nick Johnson; 12.07.2011
comment
Под собственными возможностями для списков, наборов и словарей я имел в виду (1) то, что это собственные типы данных, а не то, что мне нужно собирать из более примитивных типов, и (2) что существуют такие богатые инструменты, как пересечение, итераторы, zip, карта, уменьшение и т. д. - person Chris Johnson; 14.07.2011

Вы описываете мои сны! Однако я думаю, что вы не можете этого сделать. Я всегда хотел что-то вроде LINQ для Python, но язык не позволяет использовать синтаксис Python для собственных операций с базой данных AFAIK. Если бы это было возможно, вы могли бы просто написать код, используя списки, а затем использовать тот же код для извлечения данных из базы данных.

Я бы не рекомендовал вам писать много кода, основанного только на списках и наборах, потому что перенести его на масштабируемую платформу будет непросто. Я рекомендую вам использовать что-то вроде ORM. В GAE даже есть собственная ORM-подобная система, и вы можете использовать другие, такие как SQLAlchemy и SQLObject, например, SQLite.

К сожалению, вы не можете использовать замечательные вещи, такие как понимание списков, для фильтрации данных из базы данных. Конечно, вы можете фильтровать данные после того, как они были получены из БД, но вам все равно нужно будет построить запрос на каком-то SQL-подобном языке для запроса объектов или вернуть множество объектов из базы данных.

OTOH, есть Buzug, любопытная система нереляционных баз данных, написанная на Python, которая позволяет использовать естественный синтаксис Python. . Я никогда не использовал его, и я не знаю, является ли он масштабируемым, поэтому я бы не стал вкладывать в него свои деньги. Тем не менее, вы можете протестировать его и посмотреть, поможет ли он вам.

person brandizzi    schedule 11.07.2011
comment
Конечно, вы можете это сделать. Вы можете создать класс, который читает и записывает в базу данных, и если вы реализуете все специально названные методы (__getattr__ и т. д.), вы можете заставить его вести себя точно так же, как словарь или список. - person Bryan Oakley; 11.07.2011
comment
Что вы можете! Но ваш класс не будет отправлять различные команды в базу данных. Я имею в виду, что вы не можете написать класс, который превращал бы понимание списка, такое как [d for d in Data if d.name == "John"], в SQL-запрос, такой как SELECT * FROM Data d WHERE d.name = 'John', а затем возвращал результат запроса. Поскольку это невозможно (по крайней мере, нелегко), я бы не советовал ОП полагаться на операции со списками, если он будет управлять большим количеством данных. Я обновил свой вопрос, чтобы уточнить его. - person brandizzi; 11.07.2011
comment
@brandizzi Если у Data есть метод __iter__(), который возвращает именованные кортежи, поля которых являются полями базы данных, это действительно возможно. См. docs.python.org/dev /py3k/reference/ и docs.python. org/dev/py3k/library/. Это не должно быть так сложно. - person Evpok; 11.07.2011
comment
@brandizzi: почему ты говоришь, что не можешь этого сделать? Это может быть медленно, но вполне возможно и не так уж сложно. Очевидно, вы можете написать код, который запрашивает базу данных и возвращает список, и легко преобразовать функцию, возвращающую список, в возвращающий генератор, поэтому можно сделать и то, и другое в одной функции. - person Bryan Oakley; 12.07.2011
comment
Ну, то, что я говорю, невозможно (или, по крайней мере, очень сложно), это генерировать операторы SQL из некоторых операций со списками, таких как понимание списка. Я действительно не понимаю, как это можно сделать (по крайней мере, не имея дело с внутренностями CPython). Я знаю, что не только возможно, но и распространено обращение с результатами запроса в виде списков - у меня есть сомнения, что возможно сгенерировать какой-либо запрос к базе данных с помощью синтаксиса Python, как это делает LINQ. Однако я был бы очень удивлен и счастлив, если бы ошибся. Если вы знаете какой-то пример того, как это сделать, даже базовый, я бы хотел увидеть. - person brandizzi; 12.07.2011
comment
@Bryan Как он говорит в своем ответе, вам нужно будет получить все результаты, а затем отфильтровать их с помощью понимания списка, которое не будет масштабироваться. - person Nick Johnson; 12.07.2011

Вы можете использовать ORM: реляционное сопоставление объектов: класс получает таблицу, объекты получают строку. Мне нравится Django ORM. Вы также можете использовать его для не-веб-приложений. Я никогда не использовал это на GAE, но я думаю, что это возможно.

person guettli    schedule 11.07.2011
comment
App Engine не использует реляционную базу данных, поэтому нет, вы не можете использовать реляционное сопоставление. - person Wooble; 11.07.2011
comment
django-nonrel (allbuttonspressed.com/projects/django-nonrel) предоставляет модели ORM. для GAE точно так же, как для баз данных SQL. Но AFAIK это все еще работа. - person guettli; 13.07.2011