如何将一个python字典浸入到MySQL中?

我浏览了几个SO-Questions,以了解如何腌制python对象并将其存储到数据库中。 我收集的信息是:

  • import pickleimport cpickle 。 如果性能是一个问题,则导入后者。
  • 假设dict是一个python字典(或者python对象): pickled = pickle.dumps(dict)
  • pickled用什么那么模块数据库进行通信到MySQL BLOB列。
  • 再次出来。 并使用pickle.loads(pickled)来恢复python字典。
  • 我只是想确保我明白这个权利。 我错过了关键的事情吗? 有副作用吗? 这真的很简单吗?

    背景信息:我想要做的唯一事情就是存储Googlegeocoder-Responses,它是嵌套python字典在我的情况。 我只使用响应对象的一小部分,我不知道以后我是否会需要更多。 这就是为什么我想存储响应以节省我重复数百万个查询的原因。


    这真的很简单......只要你不需要你的数据库就能知道字典的任何内容。 如果你需要任何形式的结构化数据访问字典的内容,那么你将不得不更多地参与。

    另一个问题可能是你打算在字典中加入的内容。 Python的pickle序列化非常聪明,可以处理大多数情况,而无需添加任何定制支持。 但是,当它不起作用时,可能很难理解出了什么问题。 所以如果可以的话,将dict的内容限制在Python的内置类型中。 如果您开始添加自定义类的实例,请将它们保留为简单的自定义类,这些类不会使用任何有趣的属性存储或访问。 并且要小心从插件中添加类或类型的实例。 一般来说,如果您开始在酸洗或拆卸时遇到难以理解的问题,请查看字典中的非内置类型。


    如果速度真的很重要,我只是运行一个测试,从pickle中加载大型python字典(35MB),从MySql表中选择所有键和值存储在行中的SELECTING:

    泡菜方法:

    import time, pickle
    t1 = time.clock()
    f = open('story_data.pickle','rb')
    s = pickle.load(f)
    print time.clock() - t1
    

    MySQL方法:

    import database as db
    t1 = time.clock()
    data,msg = db.mysql(""" SELECT id,story from story_data;""")
    data_dict = dict([(int(x),y.split(',')) for x,y in data])
    print time.clock() - t1
    

    输出:pickle方法:32.0785171704 mysql方法:3.25916336479

    如果十倍速度增强足够,数据库的结构可能并不重要。 注意我将所有逗号分隔的数据拆分为36,000个键的值,并且只需要3秒。 所以我已经不再使用大量数据集的酱菜了,因为我使用的400行程序的其余部分花费了大约3秒,而咸菜加载花费了32秒。

    另请注意:

    cPickle就像咸菜一样工作,速度超过50%。

    不要试图腌制一个充满字典的类并保存在mysql中:它不能正确重构,至少它不适合我。


    如果你有嵌套字典,你必须小心。 大多数python对象不会使用pickle(并且可以将任何对象填充为dict的值)。 更糟糕的是,甚至更少的python对象可以转换为字符串并存储在SQL中。

    但是,如果使用klepto ,数据库中的序列化和存储是非常透明的,并且适用于大多数python对象。

    让我们在一个dict (或字典)中构建一些典型的python对象:

    >>> class Foo(object):                                 
    ...   def bar(self, x):
    ...     return self.y + x
    ...   y = 1
    ... 
    >>> d1 = {'a': min, 'b': lambda x:x**2, 'c': [1,2,3], 'd': Foo()}
    >>> f = Foo(); f.y = 100
    >>> d2 = {'a': max, 'b': lambda x:x**3, 'c': [2,1,3], 'd': f}
    

    现在,让我们构建一个嵌套的dict ,然后转储到MYSQL存档。

    >>> import klepto
    >>> a = klepto.archives.sql_archive('mysql://user:pass@localhost/foo', dict={'d1':d1, 'd2':d2})
    >>> a.dump()
    

    现在,我们删除我们的存档界面...并构建一个新的界面。 load将所有对象加载到内存中。

    >>> del a
    >>> b = klepto.archives.sql_archive('mysql://user:pass@localhost/foo')
    >>> b.load()
    

    我们现在访问内存副本中的对象。

    >>> b['d1']
    {'a': <built-in function min>, 'c': [1, 2, 3], 'b': <function <lambda> at 0x1037ccd70>, 'd': <__main__.Foo object at 0x103938ed0>}
    >>> b['d1']['b'](b['d1']['d'].bar(1))
    4
    >>> b['d2']['b'](b['d2']['d'].bar(1))
    1030301
    >>> 
    

    我们退出python ...然后开始新的会话。 这一次,我们决定使用cached=False ,所以我们将直接与数据库进行交互。

    dude@hilbert>$ python
    Python 2.7.10 (default, May 25 2015, 13:16:30) 
    [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import klepto
    >>> b = klepto.archives.sql_archive('mysql://user:pass@localhost/foo', cached=False)
    >>> b['d2']['b'](b['d2']['d'].bar(1))
    1030301
    >>> b['d1']['b'](b['d1']['d'].bar(1))
    4
    >>> 
    

    klepto利用sqlalchemy ,因此它可以在多个后端数据库......,另外,提供了相同的dict基于接口的磁盘存储(在一个文件或目录)。

    链接地址: http://www.djcxy.com/p/9017.html

    上一篇: How to Pickle a python dictionary into MySQL?

    下一篇: How to delete pushed commits and revert to old commit?