如何使用字典将多个值赋给一个键?

2024-09-27 00:19:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个html表单,它有FirstnameLastNameAge和{}和ADD按钮。 我把数据输入表单,然后进入Berkeelys数据库。我的代码只打印最后一个值。我希望它应该显示与特定键相关的所有值

#!/usr/bin/python

import bsddb
import cgi

form = cgi.FieldStorage()

print "Content-type:text/html\n"
Fname = form.getvalue('firstname', '')
Lname = form.getvalue('lastname', '')
Age = form.getvalue('age', 0)
Gender = form.getvalue('gender', '')

#print Fname, Lname, Age 

db = bsddb.hashopen("/home/neeraj/public_html/database/mydb.db","w")
db['FirstName'] = Fname  
db['LastName'] = Lname
db['Age'] = Age 
db['Gender'] = Gender
db.close()
db = bsddb.hashopen("/home/neeraj/public_html/database/mydb.db","r")
#db = bsddb.hashopen("/home/neeraj/public_html/database/mydb.db")
print db['FirstName'], db['LastName'], db['Age'], db['Gender']
db.close()
print db 

Tags: formhomedbagehtmlpublicgenderfname
3条回答

通过设置duplicate标志,可以在berkeley数据库中针对单个密钥保存多个值

filename = '/path/to/berkeley/db/file'
fruitDB = db.DB()
fruitDB.set_flags(db.DB_DUP)
fruitDB.open(filename, None, db.DB_BTREE, db.DB_CREATE)
fruitDB.put(str(1), "Waqar")
fruitDB.put(str(1), "Umer")
fruitDB.put(str(2), "x")
fruitDB.put(str(2), "y")
fruitDB.put(str(4), "z")
fruitDB.put(str(5), "e")

但是您不能使用BDB的“Get”方法检索所有这些项,您必须使用cursor检索项请参见documentation为此,或者可以使用

^{pr2}$

输出将是

('1', 'Waqar')
('1', 'Umer')

这将返回所有值属于键“1”的元组列表 希望这有帮助。在

您应该使用SQL数据库而不是基于dict的接口,因为SQL数据库已经处理了一个表中的多个元组。在

无论如何,如果您想要一个dict接口,您可以使用shelve模块(bsddb不推荐使用,因此您应该避免它),并将每个值保存在list中:

import shelve

COLUMNS = ('FirstName', 'LastName', 'Age', 'Sex')

the_db = shelve.open('test.db', writeback=True)
for col_name in COLUMNS:
    if col_name not in the_db:
        the_db[col_name] = []

records = [
    ('John', 'Deer', 20, 'M'),
    ('Ada', 'Lovelace', 23, 'F'),
]

for record in records:
    for col_name, value in zip(COLUMNS, record):
        the_db[col_name].append(value)

the_db.close()

the_db = shelve.open('test.db')

for record in zip(*(the_db[col_name] for col_name in COLUMNS)):
    print(record)

the_db.close()

以上代码输出:

^{pr2}$

如果要使用SQL数据库,可以使用sqlite3模块。 例如:

import sqlite3

conn = sqlite3.connect('test.sqlite')

cursor = conn.cursor()

cursor.execute('''
CREATE TABLE people (
    FirstName text,
    LastName text,
    Age int,
    Sex text
    )''')

cursor.execute('''
INSERT INTO people values ('John', 'Deer', 20, 'M')''')

cursor.execute('''
INSERT INTO people values ('Ada', 'Lovelace', 23, 'F')''')

conn.commit()

for record in cursor.execute('''SELECT * FROM people'''):
    print(record)

以上代码输出:

(u'John', u'Deer', 20, u'M')
(u'Ada', u'Lovelace', 23, u'F')

(注意u'...'只是表示字符串是unicode,它不会改变它们的值)

然而,这段代码有一些问题(例如,尝试运行两次……),但是如果您想遵循这条路径,那么您必须先学习SQL,所以请继续学习(有很多在线教程)。例如w3schools个)。在

将多个值关联到一个键的正确方法是使用例如json.dumps文件". 在

以下是一个例子:

#!/usr/bin/python
from json import dumps
from json import loads
import bsddb

# write
users = bsddb.hashopen("users.db","w")
primarykey = 'amz'
users[primarykey] = dumps(dict(username="amz", age=30, bio="craftsman"))
users.close()

# read

users = bsddb.hashopen("users.db","r")

for key in users.keys():
    print loads(users[key])

users.close()

这是与bsddb一起使用的基本模式,适用于其他键/值dbs,如leveldb。在

额外:

考虑到bsddb hashmap键是按字典顺序排序的(例如python2字符串),您可以使用键的可预测顺序来构建hashmap,从而省去遍历所有表的麻烦。在

为了更好地利用这个特性,你必须建立有用的键。同样,您需要一个打包函数,将python排序顺序转换为lexigraphic顺序(即11 > 2但是"11" < "2")。下面是这样一个包装函数的例子:

^{pr2}$

这有点天真,你可以多做一点,支持float和更好的打包{}来节省空间。在

例如,给定简化模式User(username, age),您可以构建另一个我们称为age_index的哈希映射,使用它可以轻松地检索到 30岁。hashmap可以如下所示:

   key    | value
 -----------------
  29  tom |   X
  30  amz |   X
  30  joe |   X
  30  moh |   X

这是一个人类可读的hasmap视图:密钥实际上与上面的pack函数打包在一起。如您所见,键是age的组合,以及之前存储的项的primarykey。在这种情况下,不使用该值,因为我们不需要它。请记住,每个键都是且必须是唯一的。在

一旦该模式就位,您就可以使用^{}执行“选择查询”,在bsddb中称为范围查询。这将把光标设置在最近的键上,并返回关联的键/值对(根据数据库,语义可能会有所不同)。在

例如,要检索第一个拥有age=30的人,可以使用以下代码:

def get_first_person_with_age_thirty()
    key, _ = age_index.set_range(pack(30))  # we don't need value
    age, pk = unpack(key)
    # set_range, will set the key to "30" and a pk
    # or with a key prefix superior to 30.
    #  So we need to check that age is really 30.
    if age == 30:
        return loads(users[pk])

这将返回与用户amz关联的文档。在

要进一步,需要使用另一个bsddb接口,它的入口点是bsddb.db.DB和{}(documentation)。通过这个接口,您可以将多个hashmap绑定到同一个事务上下文,即使它不需要使用事务。在

相关问题 更多 >

    热门问题