日期:2014-05-16  浏览次数:20694 次

新手学python(2):C语言调用完成数据库操作

继续介绍本人的python学习过程。本节介绍如何利用python调用c代码。内容还是基于音乐信息提取的过程,架构如图一。Python调用c实现的功能是利用python访问c语言完成mysql数据库操作。


在利用python调用c语言之前,我们需要首先完成c语言功能代码,然后再考虑语言的转换问题,所以我们先介绍c语言实现的数据库访问代码。数据库操作主要包括DDL和DML,DDL在创建数据库和表时完成,c语言完成的是DML。在具体的实现中,c语言主要完成了:连接数据库,insert和select三个操作。可以认为音乐信息数据库是一个read-only数据库,只允许添加和检索,不允许删除(删除可以通过直接操作数据库完成)。

1. 数据库设计

       关于音乐信息的数据库只有一个表格:all_music,创建表的SQL语句如下:

create table all_music(
    id integer auto_increment not null primary key,
    original_name varchar(100),
    name varchar(500) not null,
    artist varchar(500),
    genre varchar(30),
    album varchar(500),
    release_date date,
    directory varchar(300),
    size integer
);

由于音乐没有很好的主键,所以我们采用surrogate key,并设定其为自动增长的字段。其他信息主要包括音乐名,歌手,专辑,类型和发行时间等。

2. C语言操作数据库

定义完数据库表格,我们就可以实现访问该表格的c代码,相关代码如下:

#include <mysql.h>

typedef struct
{
    char original_name[100];
    char name[500];
    char artist[500];
    char genre[30];
    char album[500];
    char date[20];
    char directory[300];
    int size;
}music;

typedef struct
{
    char id[20];
    char original_name[100];
    char directory[300];
}row_result;

char* column_name[8]={"original_name","name","artist","genre","album","release_date","directory","size"};

MYSQL * connect_to(char* host,char* database,char* user,char* password)
{
    MYSQL* con_ptr;
    con_ptr=mysql_init(NULL);

    if((con_ptr=mysql_real_connect(con_ptr,host,user,password,database,3306,NULL,0))==NULL)
    {
        fprintf(stderr,"connect failed:%s\n",mysql_error(con_ptr));
        exit(-1);
    }

    return con_ptr;
}

void close_connect(MYSQL * con_ptr)
{
    mysql_close(con_ptr);
}

void insert(MYSQL * con_ptr,char* table,music* m)
{
    int res;

    char sql[2000];
    sprintf(sql,"insert into %s(%s,%s,%s,%s,%s,%s,%s,%s) values ('%s','%s','%s','%s','%s','%s','%s','%d')",table,column_name[0],column_name[1],column_name[2],column_name[3],column_name[4],column_name[5],column_name[6],column_name[7],m->original_name,m->name,m->artist,m->genre,m->album,m->date,m->directory,m->size);

    res=mysql_query((MYSQL*)con_ptr,sql);

    if(res)
    {
        fprintf(stderr,"insert failed:%s",mysql_error(con_ptr));
        return;
    }
}

MYSQL_RES * select_music(MYSQL * con_ptr,char* table)
{
    int res;

    char sql[100];
    sprintf(sql,"select id,original_name,directory from %s ",table);

    res=mysql_query((MYSQL*)con_ptr,sql);

    if(res)
    {
        fprintf(stderr,"select failed:%s",mysql_error(con_ptr));
        return NULL;
    }
    else
    {
        MYSQL_RES* result=mysql_store_result((MYSQL*)con_ptr);

        if(result) return result;
        else return NULL;
    }
}

row_result * fetch_row(MYSQL_RES * result)
{
    MYSQL_ROW mysql_row;

    if(result==NULL)
        return NULL;

    mysql_row=mysql_fetch_row((MYSQL_RES*)result);

    if(mysql_row)
    {
        row_result* row=(row_result*)malloc(sizeof(row_result));
        strcpy(row->id,mysql_row[0]);
        strcpy(row->original_name,mysql_row[1]);
        strcpy(row->directory,mysql_row[2]);

        return row;
    }
    else
    {
        fprintf(stderr,"no rows to return!\n");
        return NULL;
    }
}

void free_row(row_result * row)
{
    free(row);
}

void free_result(MYSQL_RES * result)
{
    mysql_free_re