如何在python中设计一个类似dict的sqlite类,它可以使用不同的字段作为;钥匙;?
我有一个这样的数据结构如何在python中设计一个类似dict的sqlite类,它可以使用不同的字段作为;钥匙;?,python,sqlite,dictionary,key,Python,Sqlite,Dictionary,Key,我有一个这样的数据结构 "ID NAME BIRTH AGE SEX" ================================= 1 Joe 01011980 30 M 2 Rose 12111986 24 F 3 Tom 31121965 35 M 4 Joe 15091990 20 M 我想使用python+sqlite以一种简单的方式存储和查询数据。我正在尝试设计一个类似dict
"ID NAME BIRTH AGE SEX"
=================================
1 Joe 01011980 30 M
2 Rose 12111986 24 F
3 Tom 31121965 35 M
4 Joe 15091990 20 M
我想使用python+sqlite以一种简单的方式存储和查询数据。我正在尝试设计一个类似dict的对象来存储和检索这些信息,而且数据库可以方便地与其他应用程序共享。(只是其他应用程序的一个普通数据库表,,那么pickle和ySerial的对象就不适合它了
)
例如:
d = mysqlitedict.open('student_table')
d['1'] = ["Joe","01011980","30","M"]
d['2'] = ["Rose","12111986","24","F"]
d['Joe'] = ["1","01011980","30","M"]
这可能是合理的,因为我可以使用\uuuuu setitem\uuuu()
来使用if“ID”作为键,rest部分作为dict-like对象的值
问题是如果我想在语义上使用其他字段作为键,以“NAME”为例:
d = mysqlitedict.open('student_table')
d['1'] = ["Joe","01011980","30","M"]
d['2'] = ["Rose","12111986","24","F"]
d['Joe'] = ["1","01011980","30","M"]
这将是一个问题,因为类似dict的对象在语义上应该有一个键/值对,因为现在“ID”是键,“NAME”不能像这里那样重写键
那么我的问题是,我能设计我的课堂吗?我可以这样做吗
d[key="NAME", "Joe"] = ["1","01011980","30","M"]
d[key="ID",'1'] = ["Joe","01011980","30","M"]
d.update(key = "ID", {'1':["Joe","01011980","30","M"]})
>>>d[key="NAME", 'Joe']
["1","Joe","01011980","30","M"]
["1","Joe","15091990","20","M"]
>>>d.has_key(key="NAME", 'Joe']
True
如有任何回复,我将不胜感激
KCsqlite
是一个SQL数据库,在这样使用时工作得最好(如果您真的坚持,可以用包装或其他方式;-)
像d[key=“NAME”,'Joe']
这样的语法根本就是非法的Python,不管你做了多少包装和吹嘘。围绕DB连接的简单类包装器很容易实现,但它永远不会给出这种语法——类似于d.fetch('Joe',key='Name')
的东西相当容易实现,但是索引与函数调用的语法非常不同,即使在后一种情况下,命名参数也必须位于位置参数之后
如果您愿意放弃雄心勃勃的语法梦想,转而选择明智的Python语法,并且需要帮助设计一个类来实现后者,当然,请随时提问(我很快就要上床睡觉了,但我相信其他人,以后的睡眠者会很乐意提供帮助;-)
Edit:鉴于OP的澄清(在注释中),似乎可以使用set\u key
方法来维护Python可接受的语法(尽管语义当然仍有点模糊,因为OP需要“dict-like”对象,该对象可能具有非唯一的键(Python中没有这样的键,真的……但是,我们至少可以对其进行一点近似)
因此,这里是第一个草图(需要Python2.6或更高版本——因为我使用了collections.MutableMapping
来获得其他类似dict的方法,并使用.format
来格式化字符串;如果您被困在2.5中,%-格式化字符串和UserDict.DictMixin将起作用):
该类不是直接实例化的(尽管可以通过使用适当的SqliteDict
表将打开的sqlite3连接传递到DB来实例化),而是通过两个类方法create
(创建新的DB或删除现有的DB)和open
,这似乎比备选方案更符合OP的愿望(让\uuuu init\uuuuu
获取一个DB文件路径和一个描述如何打开它的选项字符串,就像gdbm
等模块一样,获取--'r'
以只读方式打开,'c'
以创建或删除,'w'
以读写方式打开--当然很容易调整)。在传递的列中(以空格分隔的字符串形式)若要创建
,必须有一个名为的ID
(对于构建和使用此类实例时可能出现的众多用户错误中的任何一个,我都不太注意提出“正确的”错误;错误将发生在所有不正确的使用上,但不一定是用户显而易见的错误)
一旦打开(或创建)实例,它的行为将尽可能接近dict,除了设置的所有值必须是长度完全正确的列表,而返回的值是列表列表列表(由于奇怪的“非唯一键”问题)。例如,上面的代码在运行时打印
2 items in table created.
[['Rose', '12111986', '24', 'F']]
[['Joe', '01011980', '30', 'M']]
2 items in table opened.
[['1', '01011980', '30', 'M']]
“Pythonically荒谬”的行为是d[x]=d[x]
将失败——因为右侧是一个列表,例如包含一个项目(这是一个列值列表),而项目分配绝对需要一个包含四个项目(列值)的列表这种荒谬存在于OP要求的语义中,只有通过再次彻底改变这种荒谬的要求语义才能改变(例如,强制项目分配在RHS上有一个列表,并使用executemany
代替普通的execute
)
键的非唯一性也使得猜测d[x]=v
是不可能的,因为一个键k
对应于一些表项的n
,它意味着替换一个(如果是的话,哪个一个?!)或所有这些项,或者添加另一个新项“添加另一个条目”解释,但使用SQL语句REPLACE
,如果CREATE TABLE
被更改为指定一些唯一性约束,则在违反唯一性约束的情况下,将一些语义从“add entry”更改为“REPLACE entries”
我将让大家一起玩这段代码,并反映出Python映射和关系表之间的语义鸿沟有多大,OP非常希望能够弥合这一鸿沟(显然,这是他渴望“使用比SQL更好的语法”的一个副作用——我想知道他是否像我建议的那样看待SqlAlchemy)
我认为,最后,重要的教训是我在开始时,在我昨天写的答案部分的第一段中所说的,我自己引用…:
sqlite
是一个SQL数据库,可以正常工作
迄今为止,最好是这样使用(包装
如果你愿意的话
真的坚持;-)
谢谢Alex,我只是试着用蟒蛇的语法来编故事