C++调用Python3访问Sqlite数据库

SqliteEngine.py

import sqlite3 #导入模块

class SqliteEngine:
    def __init__(self,db_name):
        self.db_name = db_name
        try:
            self.conn = sqlite3.connect(db_name)#连接数据库
            self.cur = self.conn.cursor()
            print("db:" + db_name + "open succeed!")
        except Exception as err:
            print(str(err))

    def close(self):
        try:
            self.conn.close()
            print("close db")
        except Exception as err:
            print(str(err))  

    def query(self,sql):
        try:
            self.cur = self.conn.cursor()
            self.cur.execute(sql)
            print('['+sql+']' + "success")
            return self.get_recodeset(self.cur)
        except Exception as err:
            print(str(err))
            return None

    def exec(self,sql):
        try:
            self.cur = self.conn.cursor()
            self.cur.execute(sql)
            self.conn.commit()
            print('['+sql+']' + "success")
            return 0
        except Exception as err:
            self.conn.rollback()
            print(str(err))
            return -1
        
    def get_recodeset(self,cur):
        recodeset = cur.fetchall()#获取记录集
        field = [field_name[0] for field_name in cur.description]#记录集字段列表
        
        ret_list=[]#空列表
        for each_item in recodeset:
            recode_dic={};#空字典
            col_index=0
            for each_col in each_item:
                '''因为调用的C/C++中使用多字符集且可能包含汉字 使用utf8中文会乱码'''
                key = str(field[col_index]).encode("gbk","ignore")
                value = str(each_col).encode("gbk","ignore")
                recode_dic[key] = value
                col_index+=1
            ret_list.append(recode_dic)
        return  tuple(ret_list)


SqliteEngine.h

#ifndef SQLITEENGINE_H_
#define SQLITEENGINE_H_

#include <Python.h>
#include <string>
#include <vector>
#include <map>

using namespace std;

typedef		vector<map<string,string> > Recodeset;//查询结果记录集
typedef		map<string,string>			Recode;//单条记录
typedef		Recodeset::iterator			PRecodeset;
typedef		Recode::iterator			PRecode;

class SqliteEngine
{
public:
	SqliteEngine(string py);
	~SqliteEngine(void);

	static bool initPython();
	static bool unInitPython();

	bool	open(string db_name);

	void	close();
	
	int		query(string sql,Recodeset& Rec);

	int		execute(string sql);

private:
	PyObject*	m_pModule;
	PyObject*	m_pPySqlite;
	string		m_Py_module_name;
};

#endif //SQLITEENGINE_H_


SqliteEngine.cpp

#include "SqliteEngine.h"

SqliteEngine::SqliteEngine(string py)
	:m_pModule(NULL),
	m_pPySqlite(NULL),
	m_Py_module_name(py)
{
}

SqliteEngine::~SqliteEngine()
{
	SqliteEngine::unInitPython();
	m_pModule = NULL;
	m_pPySqlite = NULL;
}

bool SqliteEngine::initPython()
{
	Py_Initialize();
	//Py_IsInitialized返回0代表未初始化Python运行环境
	return Py_IsInitialized()?true:false;
}


bool SqliteEngine::unInitPython()
{
	Py_Finalize();
	return Py_IsInitialized()?false:true;
}
  

bool SqliteEngine::open(string db_name)
{
	//导入Python模块
	m_pModule = PyImport_ImportModule(m_Py_module_name.c_str());//*.py,不加后缀
	if (!m_pModule)
	{
		printf("Can not open python file!\n");
		return false;
	}
	
	//获取类SqliteEngine
	PyObject* pClass = PyObject_GetAttrString(m_pModule,"SqliteEngine");
	if (!pClass)
	{  
		printf("Can not find class [SqliteEng]!\n");
		return false;  
	}
	
	//参数
	PyObject* pArg = PyTuple_New(1);
	PyTuple_SetItem(pArg, 0, Py_BuildValue("s",db_name.c_str()));
	
	//构造SqliteEngine实例
	m_pPySqlite= PyEval_CallObject(pClass,pArg);
	if (!m_pPySqlite) 
	{  
		printf("Can not find instance!\n");
		return false;  
	}
	return true;
}

void SqliteEngine::close()
{
	if(!m_pPySqlite)
	{
		return;
	}
	PyObject_CallMethod(m_pPySqlite,"close",NULL);
}

int SqliteEngine::execute(string sql)
{
	if(!m_pPySqlite)
	{
		return -1;
	}
	int nRet = 0;
	PyObject* py_ret = PyObject_CallMethod(m_pPySqlite,"exec","s",sql);
	PyArg_Parse(py_ret,"i",&nRet);

	return nRet;
}

int SqliteEngine::query(string sql,Recodeset& Rec)
{
	if(!m_pPySqlite)
	{
		return -1;
	}

	PyObject* tuple = PyObject_CallMethod(m_pPySqlite, "query", "s",sql.c_str() );
	if(!tuple)
	{
		return -1;
	}

	Py_ssize_t tuple_size = PyTuple_Size(tuple);
	PyObject* dic = NULL;
	Py_ssize_t dic_pos = 0;
	PyObject *_key = NULL;
	PyObject *_value = NULL;
	const char* c_sKey	=NULL;
	const char* c_sVal = NULL;


	if( tuple && tuple_size>0 )
	{
		//遍历元组
		for(Py_ssize_t i=0;i<tuple_size;i++)
		{
			dic = PyTuple_GetItem(tuple,i);
			dic_pos = 0;
			
			//遍历字典
			Recode _map;
			while ( PyDict_Next(dic,&dic_pos,&_key,&_value) ) 
			{
				c_sKey = PyBytes_AsString(_key);
				c_sVal = PyBytes_AsString(_value);

				if(c_sKey)
				{
					_map.insert(make_pair(c_sKey,c_sVal));
				}
			}
			Rec.push_back(_map);
		}
	}
	return Rec.size();
}



测试驱动

#include <stdio.h>
#include <stdlib.h>
#include "SqliteEngine.h"


int main()
{
	SqliteEngine::initPython();

	SqliteEngine m("SqliteEngine");
	m.open("center.db");

	Recodeset r;
	system("echo [%time%]");
	int ret = m.query("select * from goodslist",r);
	system("echo [%time%]");

	m.close();

	system("PAUSE");

	if(ret >0)
	{
		for(size_t i=0;i<r.size();i++)
		{
			for(PRecode it_m =  r.at(i).begin();it_m !=  r.at(i).end(); it_m++)
			{
				if(it_m->second.length()> 0 )
				{
					printf("%s:[%s]\n",it_m->first.c_str(),it_m->second.c_str());
				}
				else
				{
					printf("%s:[%s]\n",it_m->first.c_str(),"没有哦");
				}
				
			}
			printf("-------------------------------\n");
		}
	}
	
	system("PAUSE");
	return 0;
}


你可能感兴趣的:(C++调用Python3访问Sqlite数据库)