问题 可以使用数据库无形地实现Python列表,集合或字典吗?


列表,集合和词典的Python原生功能完全摇滚。当数据变得非常大时,有没有办法继续使用本机功能?我正在处理的问题涉及非常大的列表的匹配(交集)。我还没有突破限制 - 实际上我并不知道限制是什么 - 并且不希望在数据按预期增长之后重新实现大的重复。

是否合理部署在谷歌应用引擎之类的东西上,宣传没有实际的规模限制并继续使用本机功能,而不是真的考虑这个?

是否存在一些Python魔法可以隐藏列表,集合或字典是否在Python管理的内存中而不是数据库中 - 因此数据的物理部署可以与我在代码中的操作保持不同?

你是这样的,Python先生还是Python超级专家,随着数据量的增长处理列表,设置和决策?


4159
2017-07-11 12:46


起源

也许你需要SQLAlchemy?还是另一个ORM?并将数据保存到数据库? - Denis
先生和女士 Python超级专家 叫做 pythonistas。 ;-) - Aufwind
如果不是不可能的话,对任意Python对象进行序列化和反序列化是非常困难的,但使用pickle / json或其他方法很容易持久化Python对象的子集,如int,str,list和dict。但是,数据持久性只包含问题的一小部分。要解决的另一个问题是,您需要创建某种映射器以将对象映射到数据库。如果您使用Postgresql或MySQL之类的关系数据库,您可以查看像Sqlalchemy这样的ORM,但如果您只能使用GAE的bigtable,那么您可能需要编写自己的ORM ... - Overmind Jiang
@Druss:不是官方的,也不会是。对我自己来说,我是一个耍蛇人。 - Chris Morgan
@Druss,我第一次听到 耍蛇人。听起来也很整洁。 ;-) - Aufwind


答案:


我不太清楚你的意思 列表,集和词典的本机功能。但是,您可以创建模拟的类 容器类型 和 序列类型 通过定义一些 具有特殊名称的方法。这意味着您可以创建一个行为类似于列表的类,但将其数据存储在SQL数据库或GAE数据存储区中。简单来说,这就是ORM的作用。但是,将对象映射到数据库非常复杂,创建自己的ORM可能不是一个好主意,而是使用现有的ORM。

我担心没有一个通用的解决方案。特别是GAE不是某种Magic Fairy Dust,你可以在你的代码上撒上它来扩展它。要创建可扩展的应用程序,您必须记住几个限制。其中一些是一般的,比如 计算复杂性,其他特定于您的代码运行的环境。例如。在GAE上 最长响应时间限制为30秒 查询数据存储区的工作方式与其他数据库的工作方式不同。

在不知道具体问题的情况下很难给出任何具体的建议,但我怀疑GAE是正确的解决方案。

通常,如果您想使用大型数据集,您必须从一开始就记住这一点,否则随着数据集的增长,您将不得不重新编写代码,算法和数据结构。


8
2017-07-11 13:57



最长响应时间30秒仅适用于面向用户的请求。脱机请求限制为10分钟,后端没有执行限制。 - Nick Johnson
你是绝对正确的,谢谢你的澄清。 - Daniel Hepper
我所说的“列表,集合和词典的本机功能”是指(1)这些是本机数据类型,而不是我需要从更原始的类型组合在一起的东西,以及(2)有交叉的这样丰富的工具,迭代器,zip,map,reduce等 - Chris Johnson


你在描述我的梦想!但是,我认为你不能这样做。我一直想要的东西就像 LINQ 对于Python但该语言不允许将Python语法用于本机数据库操作AFAIK。如果可能,您可以使用列表编写代码,然后使用相同的代码从数据库中检索数据。

我不建议您仅在列表和集合中编写大量代码,因为将其迁移到可伸缩平台并不容易。我建议你使用像ORM这样的东西。 GAE甚至有 它自己的ORM系统 你可以使用其他的如 SQLAlchemy的 和 SQLObject的 与... SQLite的。

不幸的是,你不能使用列表推导等很棒的东西来过滤数据库中的数据。当然,您可以在从数据库获取数据后对数据进行过滤,但您仍需要使用某种类似SQL的语言构建查询,以查询对象或从数据库返回大量对象。

OTOH,有 Buzhug,一个用Python编写的好奇的非关系数据库系统,它允许使用自然的Python语法。我从来没有使用它,我不知道它是否可扩展,所以我不会把钱花在它上面。但是,您可以测试它,看它是否可以帮助您。


2
2017-07-11 13:30



当然你可以做到。您可以创建一个读取和写入数据库的类,如果实现了所有特别命名的方法(__getattr__等等)你可以让它的行为与字典或列表完全相同。 - Bryan Oakley
你当然可以!但是你的类不会向数据库发送各种命令。我的意思是,你不能写一个能够使列表理解的类,比如 [d for d in Data if d.name == "John"] 成为一个SQL查询,如 SELECT * FROM Data d WHERE d.name = 'John' 然后返回查询结果。由于不可能(至少不容易),如果他将管理大量数据,我不建议OP依赖列表操作。我更新了我的问题以澄清它。 - brandizzi
@brandizzi如果 Data 有一个 __iter__() 返回名为元组的方法,其字段是数据库的字段,这确实是可能的。看到 docs.python.org/dev/py3k/reference/... 和 docs.python.org/dev/py3k/library/...。应该不那么难。 - Evpok
@brandizzi:你为什么说你做不到?它可能很慢但很可能并不是那么困难。显然,你可以编写一个qieries数据库并返回一个列表的代码,并且它很容易转换返回列表的函数返回一个生成器,因此可以在一个函数中同时执行这两个操作。 - Bryan Oakley
@Bryan正如他在回答中所说,你必须获取所有结果,然后使用列表推导过滤它们,这不会扩展。 - Nick Johnson


您可以使用ORM:对象关系映射:类获取表,对象获取行。我喜欢Django ORM。您也可以将它用于非Web应用程序。我从未在GAE上使用它,但我认为这是可能的。


0
2017-07-11 13:00



App Engine不使用关系数据库,因此不能使用关系映射。 - Wooble
django-nonrel(allbuttonspressed.com/projects/django-nonrel)为SQLE提供ORM模型,就像SQL数据库一样。但是AFAIK仍然在进行中。 - guettli