python内存数据库pydblite

摘要:
最近,Pure Python引擎发现Python informix DB模块在项目开发期间对多线程的支持非常差。当两个线程同时连接到informix数据库时,数据库将报告错误,表明SQL进程正在进行中。根据python多线程机制,我们怀疑当连接到数据库时,informix将两个线程的游标标识为相同的,因此数据库将报告错误。通过python中的多进程模块,您可以讨论所有数字

 

Pure-Python engine

最近由于项目开发中发现python informixDB模块对多线程的支持非常不好,当开启两个线程同时连接informix数据库的时候,数据库会报错,显示SQL process正在进行当中,根据python 多线程的机制我们怀疑是连接数据库时,informix将两个线程的cursor识别为同一个,故数据库报错。通过python中multiprocess模块讲所有关于数据库的操作全部改为多进程。

但是这就带来另外一个问题,在之前多线程的情况下,项目中维护着一个Queue,里面存储着若干已经创建好的informix tenant pool 的instance信息,用于客户快速获取可用数据库资源。但是有了多进程的存在,每次客户取一个instance,主进程都需要从Queue中取take一个出来,与此同时take()操作会触发创建一个tenant instance,里边包含一个进程将instance信息再次存储到Queue中。这里会涉及到Queue的进程间通讯的问题。需要将Queue改为multiprocess.queue才能避免数据丢失。这里我想尝试一下用内存数据库来试着简化进程通信的步骤。

    • import class Base from module PyDbLite : from PyDbLite import Base
    • create a database instance, passing it a path in the file system : db = Base('dummy')
    • for a new database, define the field names : db.create('name','age','size') 
      You don't have to define the field types. PyDbLite will accept any value that can be serialized by the cPickle module : strings, Unicode strings, integers, floats, dates and datetimes (instances of the date and datetime classes in the datetime module), user-defined classes, etc
    • if the base exists, open it : db.open()
    • you can pass a parameter "mode" to the create() method, to specify what you want to do if the base already exists in the file system
      • mode = "open" : db.create('name','age','size',mode="open") opens the database and ignores the field definition
      • mode = "override" : db.create('name','age','size',mode="override") erases the existing base and creates a new one with the field definition
      • if mode is not specified and the base already exists, an IOError is raised
    • insert a new record
      • by keywords : db.insert(name='homer',age=23,size=1.84) 
        If some fields are missing, they are initialized with the value None
      • by positional arguments : db.insert('homer',23,1.84) 
        The arguments must be provided in the same order as in the create() method
    • save the changes on disk : db.commit() 
      If you don't commit the changes, the insertion, deletion and update operations will not be saved on disk. To return to the previous version, just open() it again (this is equivalent to rollback in transactional databases)
    • besides the fields passed to the create() method, an internal field called __id__ is added. It is a integer which is guaranteed to be unique and unchanged for each record in the base, so that it can be used as the record identifier
    • another internal field called __version__ is also managed by the database engine. It is a integer which is set to 0 when the record is created, then incremented by 1 each time the record is updated. This is used to detect concurrency control, for instance in a web application where 2 users select the same record and want to update it at the same time
    • the selection of records uses Python list comprehension syntax : 
      recs = [ r for r in db if 30 > r['age'] >= 18 and r['size'] < 2 ] 
      returns the records in the base where the age is between 18 and 30, and size is below 2 meters. The record is a dictionary, where the key is the field name and value is the field value
    • Python generator expression syntax can also be used : 
      for r in (r for r in db if r['name'] in ('homer','marge') ):
          do_something_with(r) 
      iterates on the records where the name is one of 'homer' or 'marge'
    • to iterate on all the records : 
      for r in db:
          do_something_with(r)
    • a record can be accessed by its identifier : record = db[rec_id] returns the record such that record['__id__'] == rec_id
    • finally, a shortcut can be used for simple selections : db(key1=val1,key2=val2) returns the list of records where the keys take the given value. It is equivalent to [ r for r in db if r["key1"]==val1 and r["key2"]==val2], but much more concise
    • to speed up selections, an index can be created on a field : db.create_index('age') 
      When an index is created, the database instance has an attribute (here _age : note the heading underscore, to avoid name conflicts with internal names). This attribute is a dictionary-like object, where keys are the values taken by the field, and values are the records whose field values are egal to the key : 
      records = db._age[23] returns the list of records with age == 23 
      If no record has this value, lookup by this value returns an empty list 
      The index supports iteration on the field values, and the keys() method returns all existing values for the field
    • number of records in the base : len(db)
    • to delete a record : db.delete(record) or, if you know the record identifier : del db[rec_id]
    • to delete a list of records : db.delete(list_of_records) 
      list_of_records can be any iterable (list, tuple, set, etc) yielding records
    • to update a record : db.update(record,age=24)
    • to add a new field to an existing base and specify a default value : db.add_field('new_field'[,default=v]). If no default is provided, the field value is None
    • to drop an existing field : db.drop_field('name')
    • to get the list of fields : db.fields
import pydblite
# 使用内存数据库
pydb = pydblite.Base("address")
# 创建a,b,c三个字段
pydb.create('a', 'b', 'c')
# 为字段a,b创建索引
pydb.create_index('a', 'b')
# 插入一条数据

pydb.insert(a=0, b=0, c=1)
pydb.insert(a=1, b=0, c=1)
pydb.insert(a=1, b=0, c=1)
pydb.insert(a=1, b=0, c=1)
pydb.update(records=pydb[1],a=2,c="li")
pydb.delete(pydb[0])
# 查询符合特定要求的数据
results = pydb(a=2)
for i in  results:
    print results[i]

免责声明:文章转载自《python内存数据库pydblite》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Cocos2dx-3.0版本 从开发环境搭建(Win32)到项目移植Android平台过程详解深入浅出Node.js(上)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python爬虫入门01:教你在 Chrome 浏览器轻松抓包

通过 python爬虫入门:什么是爬虫,怎么玩爬虫? 我们知道了什么是爬虫 也知道了爬虫的具体流程 那么在我们要对某个网站进行爬取的时候 要对其数据进行分析 就要知道应该怎么请求 就要知道获取的数据是什么样的 所以我们要学会怎么抓咪咪! 哦,不对。 我们要学会怎么数据抓包 虽然小馒头也是包的一种 ok...anyway... 打开我们的 Chrome...

Python中利用os模块创建目录文件

一、os.makedirs()   os.makedirs() 方法用于递归创建目录。像 mkdir(), 但创建的所有intermediate-level文件夹需要包含子目录。 import os path_01 = 'Test\path_01\path_02\path_03' try: os.mkdir(path_01) print...

五. python数据转换

1. 数据转换    set  tuple   list  dict  int   float # list ----set a1=[1,2,3,4,5,6] a2=set(a1) print(a2) #{1, 2, 3, 4, 5, 6} # tuple----set a3=(1,2,3000,4,5,600000) a4=set(a3) pr...

python系列之(4)豆瓣图书《平凡的世界》书评及情感分析

本篇主要是通过对豆瓣图书《平凡的世界》短评进行抓取并进行分析,并用snowNLP对其进行情感分析。 用到的模块有snowNLP,是一个python库,用来进行情感分析。 1.抓取数据 我们把抓取到的数据存储到sqlite,先建表,结构如下: CREATE TABLE comment( id integer PRIMARY KEY autoincre...

python 获取图片并自动命名保存

# -* - coding: UTF-8 -* -#导入第三方库import urllibfrom bs4 import BeautifulSoupimport requestsimport osimport timeimport random# 获取文件夹,如果文件夹不存在则创建新文件夹if os.path.isdir('E://biaoqing//')...

基于分布式的短文本命题实体识别之----人名识别(python实现)

目前对中文分词精度影响最大的主要是两方面:未登录词的识别和歧义切分。 据统计:未登录词中中文姓人名在文本中一般只占2%左右,但这其中高达50%以上的人名会产生切分错误。在所有的分词错误中,与人名有关的错误占到了将近90%,这中国人名都是根据人的想法起的名字,有很大的随意性,并且数量巨大,规律也不尽相同。 1.理论简介 命名实体识别(Named Ent...