可以将Python类对象存储在SQLite中吗?

57 投票
10 回答
65804 浏览
提问于 2025-04-15 17:55

我想把Python对象存储到一个SQLite数据库里。这样做可以吗?

如果可以的话,有哪些链接或者例子可以参考呢?

10 个回答

16

你可以使用 pickle.dumps,它会把可以保存的对象转换成字符串,这样你就不需要把它写入临时文件了。

这个方法会返回对象的可保存表示,作为一个字符串,而不是写入文件。

import pickle

class Foo:
    attr = 'a class attr'

picklestring = pickle.dumps(Foo)
24

是的,这是可能的,但有不同的方法,适合哪种方法取决于你的需求。

  • 序列化

    你可以使用 pickle 模块来把对象转成一种可以存储的格式,然后把这些对象放到sqlite3的一个二进制大对象中(或者如果是文本格式,比如用base64编码的话,可以放到文本字段里)。不过要注意一些可能出现的问题:questions/198692/can-i-pickle-a-python-dictionary-into-a-sqlite3-text-field

  • 对象关系映射

    你可以使用对象关系映射。这实际上创建了一个“虚拟对象数据库”,可以在编程语言中使用(维基百科)。对于Python,有一个很不错的工具包:sqlalchemy

88

你不能直接把对象放进数据库里。你需要把对象里的数据存起来,然后再把它们组合成对象。

一个很好的方法是使用优秀的 SQLAlchemy 库。这个库可以让你把定义好的类和数据库里的表对应起来。每个对应的属性都会被存储,并且可以用来重新构建对象。查询数据库时,会返回你定义的类的实例。

使用这个库,你不仅可以用sqlite,还可以用大多数数据库。目前它还支持Postgres、MySQL、Oracle、MS-SQL、Firebird、MaxDB、MS Access、Sybase、Informix和IBM DB2。你可以让用户选择想用哪个数据库,因为你几乎可以在这些数据库之间切换,而不需要改动代码。

这个库还有很多很酷的功能,比如自动的 JOIN 操作、多态等等。

这里有一个简单的例子,你可以运行一下:

from sqlalchemy import Column, Integer, Unicode, UnicodeText, String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

from random import choice
from string import letters

engine = create_engine('sqlite:////tmp/teste.db', echo=True)
Base = declarative_base(bind=engine)

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(Unicode(40))
    address = Column(UnicodeText, nullable=True)
    password = Column(String(20))

    def __init__(self, name, address=None, password=None):
        self.name = name
        self.address = address
        if password is None:
            password = ''.join(choice(letters) for n in xrange(10))
        self.password = password

Base.metadata.create_all()

Session = sessionmaker(bind=engine)
s = Session()

然后我可以这样使用它:

# create instances of my user object
u = User('nosklo')
u.address = '66 Some Street #500'

u2 = User('lakshmipathi')
u2.password = 'ihtapimhskal'

# testing
s.add_all([u, u2])
s.commit()

这样会对数据库执行 INSERT 语句。

# When you query the data back it returns instances of your class:

for user in s.query(User):
    print type(user), user.name, user.password

这个查询会执行 SELECT users.id AS users_id, users.name AS users_name, users.address AS users_address, users.password AS users_password

打印出来的结果会是:

<class '__main__.User'> nosklo aBPDXlTPJs
<class '__main__.User'> lakshmipathi ihtapimhskal

所以你实际上是在以最好的方式把对象存储到数据库里。

撰写回答