可以将Python类对象存储在SQLite中吗?
我想把Python对象存储到一个SQLite数据库里。这样做可以吗?
如果可以的话,有哪些链接或者例子可以参考呢?
10 个回答
你可以使用 pickle.dumps,它会把可以保存的对象转换成字符串,这样你就不需要把它写入临时文件了。
这个方法会返回对象的可保存表示,作为一个字符串,而不是写入文件。
import pickle
class Foo:
attr = 'a class attr'
picklestring = pickle.dumps(Foo)
是的,这是可能的,但有不同的方法,适合哪种方法取决于你的需求。
序列化
你可以使用 pickle 模块来把对象转成一种可以存储的格式,然后把这些对象放到sqlite3的一个二进制大对象中(或者如果是文本格式,比如用base64编码的话,可以放到文本字段里)。不过要注意一些可能出现的问题:questions/198692/can-i-pickle-a-python-dictionary-into-a-sqlite3-text-field
对象关系映射
你可以使用对象关系映射。这实际上创建了一个“虚拟对象数据库”,可以在编程语言中使用(维基百科)。对于Python,有一个很不错的工具包:sqlalchemy。
你不能直接把对象放进数据库里。你需要把对象里的数据存起来,然后再把它们组合成对象。
一个很好的方法是使用优秀的 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
所以你实际上是在以最好的方式把对象存储到数据库里。