2011-07-11 14 views
11

Las capacidades nativas de Python para listas, establece & diccionarios totalmente rock. ¿Hay alguna manera de continuar utilizando la capacidad nativa cuando los datos se vuelven realmente grandes? El problema en el que estoy trabajando involucraba la coincidencia (intersección) de listas muy grandes. Aún no he superado los límites (en realidad, no sé cuáles son los límites) y no quiero sorprenderme con una gran reimplementación después de que los datos crezcan como se esperaba.¿Se puede implementar una lista, un conjunto o un diccionario de Python de forma invisible utilizando una base de datos?

¿Es razonable implementarlo en algo como Google App Engine que no publicita ningún límite de escala práctica y continuar utilizando la capacidad original tal como es para siempre y no pensar realmente en esto?

¿Existe alguna magia de Python que pueda ocultar si la lista, el conjunto o el diccionario está en memoria administrada por Python en un DB, de modo que la distribución física de datos puede mantenerse distinta de lo que hago en el código?

¿Cómo maneja usted, Sr. o Sra. Python Super Expert, las listas, establece & a medida que crece el volumen de datos?

+8

Sr. y Sra. * Python Super Experts * se llaman * [pythonistas] (http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html) *. ;-) – Aufwind

+0

Es extremadamente difícil, si no imposible, serializar y deserializar objetos de Python arbitrarios, pero es fácil persistir un subconjunto de objetos de Python, como int, str, list y dict usando pickle/json o lo que sea. Sin embargo, la persistencia de los datos solo consiste en una pequeña parte de su problema. Otro problema por resolver es que necesitas crear algún tipo de mapeador para mapear tu objeto con la base de datos. Si está utilizando bases de datos relacionales como Postgresql o MySQL, puede echar un vistazo a los ORM como Sqlalchemy, pero si solo puede usar la tabla grande de GAE, es posible que necesite escribir su propio ORM ... –

+1

@Druss: no es oficial ni lo hará nunca ser. Para mí, soy un encantador de serpientes. –

Respuesta

8

No estoy muy seguro de lo que entendemos por capacidades nativas para las listas, establece & diccionarios. Sin embargo, puede crear clases que emulen container types y sequence types definiendo algunos methods with special names. Eso significa que puede crear una clase que se comporte como una lista, pero almacena sus datos en una base de datos SQL o en el almacén de datos GAE. Simplemente hablando, esto es lo que hace un ORM. Sin embargo, asignar objetos a una base de datos es muy complicado y probablemente no sea una buena idea inventar su propio ORM, sino usar uno existente.

Me temo que no hay una solución única para todos. Especialmente GAE no es un tipo de Magic Fairy Dust, puedes rociar tu código para hacerlo escalar. Hay varias limitaciones que debe tener en cuenta para crear una aplicación que pueda escalar. Algunos de ellos son generales, como computational complexity, otros son específicos del entorno en el que se ejecuta el código. P. ej.en GAE , el tiempo de respuesta máximo está limitado a 30 segundos y al consultar el almacén de datos funciona de manera diferente que en otras bases de datos.

Es difícil dar un consejo concreto sin conocer su problema específico, pero dudo que GAE sea la solución correcta.

En general, si desea trabajar con grandes conjuntos de datos, debe tenerlo en cuenta desde el principio o deberá modificar el código, los algoritmos y las estructuras de datos a medida que crecen los conjuntos de datos.

+1

El tiempo máximo de respuesta de 30 segundos solo se aplica a las solicitudes dirigidas al usuario. Las solicitudes sin conexión están limitadas a 10 minutos y los servidores no tienen límite de ejecución. –

+0

Tiene toda la razón, gracias por aclarar. –

+0

Lo que quise decir con "capacidades nativas para listas, conjuntos y diccionarios" es (1) que estos son tipos de datos nativos, no es algo que deba juntar de tipos más primitivos, y (2) que hay herramientas tan ricas como intersecciones , iteradores, zip, mapa, reducir etc. –

0

Puede usar ORM: Asignación relacional de objetos: una clase obtiene una tabla, un objeto obtiene una fila. Me gusta el Django ORM. También puede usarlo para aplicaciones que no sean web. Nunca lo usé en GAE, pero creo que es posible.

+0

App Engine no utiliza una base de datos relacional, por lo que no, no puede usar una asignación relacional. – geoffspear

+0

django-nonrel (http://www.allbuttonspressed.com/projects/django-nonrel) le ofrece Modelos ORM para GAE al igual que para bases de datos SQL. Pero AFAIK, esto todavía está en progreso. – guettli

2

¡Estás describiendo mis sueños! Sin embargo, creo que no puedes hacerlo. Siempre quise algo como LINQ para Python, pero el lenguaje no permite utilizar la sintaxis de Python para operaciones de bases de datos nativas AFAIK. Si fuera posible, podría simplemente escribir código usando listas y luego usar el mismo código para recuperar datos de una base de datos.

No le recomendaría que escriba mucho código basado solo en listas y conjuntos porque no será fácil migrarlo a una plataforma escalable. Te recomiendo usar algo como un ORM. GAE incluso tiene its own ORM-like system y puede usar otros como SQLAlchemy y SQLObject con, p. SQLite.

Desafortunadamente, no se pueden usar elementos geniales como las listas de comprensión para filtrar los datos de la base de datos. Seguramente, puede filtrar los datos después de que se obtuvieron de la base de datos, pero aún tendrá que generar una consulta con algún lenguaje similar a SQL para consultar objetos o devolver muchos objetos de una base de datos.

OTOH, hay Buzhug, un curioso sistema de base de datos no relacional escrito en Python que permite el uso de la sintaxis natural de Python. Nunca lo he usado y no sé si es escalable, así que no pondría mi dinero en él. Sin embargo, puedes probarlo y ver si te puede ayudar.

+0

Por supuesto que puedes hacerlo. Puede crear una clase que lea y escriba en una base de datos, y si implementa todos los métodos con nombre especial ('__getattr__', etc.) puede hacer que se comporte exactamente como un diccionario o una lista. –

+0

¡Claro que puedes! Pero su clase no enviaría varios comandos a la base de datos. Quiero decir, no se puede escribir una clase que haga una lista de comprensión como '[d for d in Data if d.name ==" John "]' para convertirse en una consulta SQL como 'SELECT * FROM Data d WHERE d. name = 'John'' y luego devuelve el resultado de la consulta. Como no es posible (al menos no fácilmente), no recomendaría que el OP dependa de las operaciones de la lista si administrará muchos datos. Actualicé mi pregunta para aclararla. – brandizzi

+0

@brandizzi Si 'Data' tiene un método' __iter __() 'que devuelve tuplas con nombre cuyos campos son los campos de la base de datos, de hecho es posible. Consulte http://docs.python.org/dev/py3k/reference/datamodel.html?highlight=data%20model#object.__iter__ y http://docs.python.org/dev/py3k/library/collections.html # collections.namedtuple. No debería ser tan difícil. – Evpok

Cuestiones relacionadas