我需要存储客户和他们购买的汽车的基本数据以及这些汽车的付款时间表。这些数据来自用 Python 编写的 GUI。我没有足够的经验来使用像 sql 这样的数据库系统,所以我想将我的数据作为纯文本存储在一个文件中。而且它不必在线。
为了能够搜索和过滤它们,首先我将我的数据(列表列表)转换为字符串,然后当我需要将数据重新转换为常规 Python 列表语法时。我知道这是一种非常暴力的方式,但是这样做是否安全,或者您能建议我采用另一种方式吗?
我需要存储客户和他们购买的汽车的基本数据以及这些汽车的付款时间表。这些数据来自用 Python 编写的 GUI。我没有足够的经验来使用像 sql 这样的数据库系统,所以我想将我的数据作为纯文本存储在一个文件中。而且它不必在线。
为了能够搜索和过滤它们,首先我将我的数据(列表列表)转换为字符串,然后当我需要将数据重新转换为常规 Python 列表语法时。我知道这是一种非常暴力的方式,但是这样做是否安全,或者您能建议我采用另一种方式吗?
将数据库保存为文本格式(或使用 pickle 或其他格式)是绝对不安全的。保存数据时出现问题可能会导致损坏。更不用说您的数据被盗的风险。
随着数据集的增长,性能可能会受到影响。
看看 sqlite(或 sqlite3),它比 mysql 更小且更易于管理。除非您有一个适合文本文件的非常小的数据集。
P/S:顺便说一句,在 python 中使用 berkeley db 很简单,你不必学习所有的 DB 东西,只需 import bsddb
使用泡菜的答案很好,但我个人更喜欢搁置。它允许您将变量保持在它们在两次启动之间的相同状态,我发现它比直接使用 pickle 更容易。 http://docs.python.org/library/shelve.html
我同意其他人的观点,即严肃和重要的数据在某种类型的轻型数据库中会更安全,但也可以对保持简单和透明的愿望感到同情。
因此,我建议您使用YAML,而不是发明自己的基于文本的数据格式
该格式是人类可读的,例如:
List of things:
- Alice
- Bob
- Evan
您像这样加载文件:
>>> import yaml
>>> file = open('test.yaml', 'r')
>>> list = yaml.load(file)
列表将如下所示:
{'List of things': ['Alice', 'Bob', 'Evan']}
当然,您也可以反过来将数据保存到 YAML 中,文档会为您提供帮助。
至少要考虑另一种选择:)
非常简单和基本 - (更多 @ http://pastebin.com/A12w9SVd)
import json, os
db_name = 'udb.db'
def check_db(name = db_name):
if not os.path.isfile(name):
print 'no db\ncreating..'
udb = open(db_name,'w')
udb.close()
def read_db():
try:
udb = open(db_name, "r")
except:
check_db()
read_db()
try:
dicT = json.load(udb)
udb.close()
return dicT
except:
return {}
def update_db(newdata):
data = read_db()
wdb = dict(data.items() + newdata.items())
udb = open(db_name, 'w')
json.dump(wdb, udb)
udb.close()
使用:
def adduser():
print 'add user:'
name = raw_input('name > ')
password = raw_input('password > ')
update_db({name:password})
您可以使用此库将对象写入文件http://docs.python.org/library/pickle.html
在文件中写入数据并不是一种安全的数据存储方式。最好使用像 sqlalchemy 这样的简单数据库库。它是一个便于数据库使用的 ORM...
您还可以将简单数据保存在纯文本文件中。但是,您没有太多支持来检查数据的一致性、双值等。
这是我在文本文件代码片段中使用 namedtuple的简单“卡片文件”类型数据,这样您不仅可以通过行内索引访问值,还可以通过它们的标题名称访问值:
# text based data input with data accessible
# with named fields or indexing
from __future__ import print_function ## Python 3 style printing
from collections import namedtuple
import string
filein = open("sample.dat")
datadict = {}
headerline = filein.readline().lower() ## lowercase field names Python style
## first non-letter and non-number is taken to be the separator
separator = headerline.strip(string.lowercase + string.digits)[0]
print("Separator is '%s'" % separator)
headerline = [field.strip() for field in headerline.split(separator)]
Dataline = namedtuple('Dataline',headerline)
print ('Fields are:',Dataline._fields,'\n')
for data in filein:
data = [f.strip() for f in data.split(separator)]
d = Dataline(*data)
datadict[d.id] = d ## do hash of id values for fast lookup (key field)
## examples based on sample.dat file example
key = '123'
print('Email of record with key %s by field name is: %s' %
(key, datadict[key].email))
## by number
print('Address of record with key %s by field number is: %s' %
(key ,datadict[key][3]))
## print the dictionary in separate lines for clarity
for key,value in datadict.items():
print('%s: %s' % (key, value))
input('Ready') ## let the output be seen when run directly
""" Output:
Separator is ';'
Fields are: ('id', 'name', 'email', 'homeaddress')
Email of record with key 123 by field name is: gishi@mymail.com
Address of record with key 123 by field number is: 456 happy st.
345: Dataline(id='345', name='tony', email='tony.veijalainen@somewhere.com', homeaddress='Espoo Finland')
123: Dataline(id='123', name='gishi', email='gishi@mymail.com', homeaddress='456 happy st.')
Ready
"""