#通过Python连接数据库

用Python来编写网站,必须要能够通过python操作数据库,所谓操作数据库,就是通过python实现对数据的连接,以及对记录、字段的各种操作。

##安装python-MySQLdb

要想通过python来操作数据库,还需要在已经安装了mysql的基础上安装一个称之为mysqldb的库,它是一个接口程序,python通过它对mysql数据实现各种操作。

在编程中,会遇到很多类似的接口程序,通过接口程序对另外一个对象进行操作,比较简单。接口程序就好比钥匙,如果要开锁,人直接用手指去捅,肯定是不行的,那么必须借助工具,插入到锁孔中,把所打开,打开所之后,门开了,就可以操作门里面的东西了。那么打开所的工具就是接口程序。而打开所的工具会有便利与否之分,如果用这锁的钥匙,就便利,如果用别的工具,或许不便利(其实还分人,也就是人开锁的水平,如果是江洋大盗或者小毛贼什么的,擅长开锁,用别的工具也便利了),也就是接口程序不同,编码水平不同,都是考虑因素。

这里下载python-mysqldb:https://pypi.python.org/pypi/MySQL-python/

下载之后就可以安装了。

我这里只能演示ubuntu下安装的过程。

sudo apt-get install python-MySQLdb

在shell中输入上面的命令行,就安装了。看看,多么简洁的安装,请快快用ubuntu吧。我愿意做ubuntu的免费代言。哈哈。

不管什么系统,安装不是难题。安装之后,怎么知道安装的结果呢?

>>> import MySQLdb

在python的交互模式中,输入上面的指令,如果不报错,恭喜你,已经安装好了。如果报错,恭喜你,可以借着错误信息提高自己的计算机水平了,请求助于google大神。

##交互模式下操作数据库之连接数据库

操作数据库的前提是先有数据库。

先建立一个数据库。

qw@qw-Latitude-E4300:~$ mysql -u root -p
Enter password:

打开数据库,正确输入密码之后,呈现下面的结果

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 373
Server version: 5.5.38-0ubuntu0.14.04.1 (Ubuntu)Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

在这个状态下,输入如下命令,建立一个数据库:

mysql> create database qiwsirtest character set utf8;
Query OK, 1 row affected (0.00 sec)

注意上面的指令,如果仅仅输入:create database qiwsirtest,也可以,但是,我在后面增加了character set utf8,意思是所建立的数据库qiwsirtest,编码是utf-8的,这样存入汉字就不是乱码了。

看到那一行提示:Query OK, 1 row affected (0.00 sec),就说明这个数据库已经建立好了,名字叫做:qiwsirtest

数据库建立之后,就可以用python通过已经安装的mysqldb来连接这个名字叫做qiwsirtest的库了。进入到python交互模式(现在这个实验室做实验)。

>>> import MySQLdb
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123123",db="qiwsirtest",port=3306,charset="utf8")

逐个解释上述命令的含义:

  • host:等号的后面应该填写mysql数据库的地址,因为就数据库就在本机上(也称作本地),所以使用localhost,注意引号。如果在其它的服务器上,这里应该填写ip地址。一般中小型的网站,数据库和程序都是在同一台服务器(计算机)上,就使用localhost了。
  • user:登录数据库的用户名,这里一般填写"root",还是要注意引号。当然,如果是比较大型的服务,数据库会提供不同的用户,那时候可以更改为相应用户。但是,不同用户的权限可能不同,所以,在程序中,如果要操作数据库,还要注意所拥有的权限。在这里用root,就放心了,什么权限都有啦。不过,这样做,在大型系统中是应该避免的。
  • passwd:上述user账户对应的登录mysql的密码。我在上面的例子中用的密码是"123123"。不要忘记引号。
  • db:就是刚刚通create命令建立的数据库,我建立的数据库名字是"qiwsirtest",还是要注意引号。看官如果建立的数据库名字不是这个,就写自己所建数据库名字。
  • port:一般情况,mysql的默认端口是3306,当mysql被安装到服务器之后,为了能够允许网络访问,服务器(计算机)要提供一个访问端口给它。
  • charset:这个设置,在很多教程中都不写,结果在真正进行数据存储的时候,发现有乱码。这里我将qiwsirtest这个数据库的编码设置为utf-8格式,这样就允许存入汉字而无乱码了。注意,在mysql设置中,utf-8写成utf8,没有中间的横线。但是在python文件开头和其它地方设置编码格式的时候,要写成utf-8。切记!

注:connect中的host、user、passwd等可以不写,只有在写的时候按照host、user、passwd、db(可以不写)、port顺序写就可以,注意端口号port=3306还是不要省略的为好,如果没有db在port前面,直接写3306会报错.

其实,关于connect的参数还不少,下面摘抄来自mysqldb官方文档的内容,把所有的参数都列出来,还有相关说明,请看官认真阅读。不过,上面几个是常用的,其它的看情况使用。

connect(parameters...)

Constructor for creating a connection to the database. Returns a Connection Object. Parameters are the same as for the MySQL C API. In addition, there are a few additional keywords that correspond to what you would pass mysql_options() before connecting. Note that some parameters must be specified as keyword arguments! The default value for each parameter is NULL or zero, as appropriate. Consult the MySQL documentation for more details. The important parameters are:

  • host: name of host to connect to. Default: use the local host via a UNIX socket (where applicable)
  • user: user to authenticate as. Default: current effective user.
  • passwd: password to authenticate with. Default: no password.
  • db: database to use. Default: no default database.
  • port: TCP port of MySQL server. Default: standard port (3306).
  • unix_socket: location of UNIX socket. Default: use default location or TCP for remote hosts.
  • conv: type conversion dictionary. Default: a copy of MySQLdb.converters.conversions
  • compress: Enable protocol compression. Default: no compression.
  • connect_timeout: Abort if connect is not completed within given number of seconds. Default: no timeout (?)
  • named_pipe: Use a named pipe (Windows). Default: don't.
  • init_command: Initial command to issue to server upon connection. Default: Nothing.
  • read_default_file: MySQL configuration file to read; see the MySQL documentation for mysql_options().
  • read_default_group: Default group to read; see the MySQL documentation for mysql_options().
  • cursorclass: cursor class that cursor() uses, unless overridden. Default: MySQLdb.cursors.Cursor. This must be a keyword parameter.
  • use_unicode: If True, CHAR and VARCHAR and TEXT columns are returned as Unicode strings, using the configured character set. It is best to set the default encoding in the server configuration, or client configuration (read with read_default_file). If you change the character set after connecting (MySQL-4.1 and later), you'll need to put the correct character set name in connection.charset.

If False, text-like columns are returned as normal strings, but you can always write Unicode strings.

This must be a keyword parameter.

  • charset: If present, the connection character set will be changed to this character set, if they are not equal. Support for changing the character set requires MySQL-4.1 and later server; if the server is too old, UnsupportedError will be raised. This option implies use_unicode=True, but you can override this with use_unicode=False, though you probably shouldn't.

If not present, the default character set is used.

This must be a keyword parameter.

  • sql_mode: If present, the session SQL mode will be set to the given string. For more information on sql_mode, see the MySQL documentation. Only available for 4.1 and newer servers.

If not present, the session SQL mode will be unchanged.

This must be a keyword parameter.

  • ssl: This parameter takes a dictionary or mapping, where the keys are parameter names used by the mysql_ssl_set MySQL C API call. If this is set, it initiates an SSL connection to the server; if there is no SSL support in the client, an exception is raised. This must be a keyword parameter.

我已经完成了数据库的连接,虽然是在交互模式下,看官你是否也实现了呢?下面,将开始讲述如何操作数据库。

#用Python操作数据库(1)

在面中已经连接了数据库。就数据库而言,连接之后就要对其操作。但是,目前那个名字叫做qiwsirtest的数据仅仅是空架子,没有什么可操作的,要操作它,就必须在里面建立“表”,什么是数据库的表呢?下面摘抄自维基百科对数据库表的简要解释,要想详细了解,需要看官在找一些有关数据库的教程和书籍来看看。

在关系数据库中,数据库表是一系列二维数组的集合,用来代表和储存数据对象之间的关系。它由纵向的列和横向的行组成,例如一个有关作者信息的名为 authors 的表中,每个列包含的是所有作者的某个特定类型的信息,比如“姓氏”,而每行则包含了某个特定作者的所有信息:姓、名、住址等等。

对于特定的数据库表,列的数目一般事先固定,各列之间可以由列名来识别。而行的数目可以随时、动态变化,每行通常都可以根据某个(或某几个)列中的数据来识别,称为候选键。

我打算在qiwsirtest中建立一个存储用户名、用户密码、用户邮箱的表,其结构用二维表格表现如下:

username password email
qiwsir 123123 qiwsir@gmail.com

特别说明,这里为了简化细节,突出重点,对密码不加密,直接明文保存,虽然这种方式是很不安全的。但是,有不少网站还都这么做的,这么做的目的是比较可恶的。就让我在这里,仅仅在这里可恶一次。

##建数据库表并插入数据

为了在数据库中建立这个表,需要进入到mysql>交互模式中操作。道理在于,如果qiwsirtest这个屋子里面没有类似家具的各种数据库表,即使进了屋子也没有什么好操作的东西,因此需要先到mysql>模式下在屋子里面摆家具。

进入数据库交互模式:

qw@qw-Latitude-E4300:~$ mysql -u root -p
Enter password:

调用已经建立的数据库:qiwsirtest

mysql> use qiwsirtest;
Database changed
mysql> show tables;
Empty set (0.00 sec)

show tables命令显示这个数据库中是否有数据表了。查询结果显示为空。

下面就用如下命令建立一个数据表,这个数据表的内容就是上面所说明的。

mysql> create table users(id int(2) not null primary key auto_increment,username varchar(40),password text,email text)default charset=utf8;
Query OK, 0 rows affected (0.12 sec)

建立的这个数据表名称是:users,其中包含上述字段,可以用下面的方式看一看这个数据表的结构。

mysql> show tables;
+----------------------+
| Tables_in_qiwsirtest |
+----------------------+
| users                |
+----------------------+
1 row in set (0.00 sec)

查询显示,在qiwsirtest这个数据库中,已经有一个表,它的名字是:users。

mysql> desc users;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(2)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(40) | YES  |     | NULL    |                |
| password | text        | YES  |     | NULL    |                |
| email    | text        | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

显示表users的结构:

  • id:每增加一个用户,id号自动增加一个。
  • username:存储用户名,类型是varchar(40)
  • password:存储用户密码,类型是text
  • email:存储用户的邮箱,类型是text

特别提醒:在这里,我没有对每个字段做注入不得为空等设置,在真正的开发中,或许必须让username和password不得为空。

这个结构和上面所期望的结构是一样的,只不过这个表中还没有任何数据,是一个空表。可以查询一下看看:

mysql> select * from users;
Empty set (0.01 sec)

目前表是空的,为了能够在后面用python操作这个数据表,需要向里面插入点信息,就只插入一条吧。

mysql> insert into users(username,password,email) values("qiwsir","123123","qiwsir@gmail.com");
Query OK, 1 row affected (0.05 sec)mysql> select * from users;
+----+----------+----------+------------------+
| id | username | password | email            |
+----+----------+----------+------------------+
|  1 | qiwsir   | 123123   | qiwsir@gmail.com |
+----+----------+----------+------------------+
1 row in set (0.00 sec)

到目前为止,在mysql>中的工作已经完成了,接下来就是用python操作了。

##python操作数据库

要对数据库进行操作,需要先连接它。上一讲看官连接过了,但是,随后你关闭了python的交互模式,所以还要从新连接。这也是交互模式的缺点。不过在这里操作直观,所以暂且忍受一下,后面就会讲解如何在程序中自动完成了。

>>> import MySQLdb
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123123",db="qiwsirtest",charset="utf8")

完成连接的过程,其实是建立了一个MySQLdb.connect()的实例对象conn,那么这个对象有哪些属性呢?

  • commit():如果数据库表进行了修改,提交保存当前的数据。当然,如果此用户没有权限就作罢了,什么也不会发生。
  • rollback():如果有权限,就取消当前的操作,否则报错。
  • cursor([cursorclass]):游标指针。下面详解。

连接成功之后,开始操作。注意:MySQLdb用游标(指针)cursor的方式操作数据库,就是这样:

>>> cur = conn.cursor()

因该模块底层其实是调用CAPI的,所以,需要先得到当前指向数据库的指针。这也就提醒我们,在操作数据库的时候,指针会移动,如果移动到数据库最后一条了,再查,就查不出什么来了。看后面的例子就明白了。

下面用cursor()提供的方法来进行操作,方法主要是:

  1. 执行命令
  2. 接收结果

###cursor执行命令的方法:

  • execute(query, args):执行单条sql语句。query为sql语句本身,args为参数值的列表。执行后返回值为受影响的行数。
  • executemany(query, args):执行单条sql语句,但是重复执行参数列表里的参数,返回值为受影响的行数

例如,要在数据表users中插入一条记录,使得:username="python",password="123456",email="python@gmail.com",这样做:

>>> cur.execute("insert into users (username,password,email) values (%s,%s,%s)",("python","123456","python@gmail.com"))
1L

没有报错,并且返回一个"1L"结果,说明有一行记录操作成功。不妨用"mysql>"交互方式查看一下:

mysql> select * from users;
+----+----------+----------+------------------+
| id | username | password | email            |
+----+----------+----------+------------------+
|  1 | qiwsir   | 123123   | qiwsir@gmail.com |
+----+----------+----------+------------------+
1 row in set (0.00 sec)

咦,奇怪呀。怎么没有看到增加的那一条呢?哪里错了?可是上面也没有报错呀。

在这里,特别请列位看官注意,通过"cur.execute()"对数据库进行操作之后,没有报错,完全正确,但是不等于数据就已经提交到数据库中了,还必须要用到"MySQLdb.connect"的一个属性:commit(),将数据提交上去,也就是进行了"cur.execute()"操作,要将数据提交,必须执行:

>>> conn.commit()

在到"mysql>"中运行"select * from users"试一试:

mysql> select * from users;
+----+----------+----------+------------------+
| id | username | password | email            |
+----+----------+----------+------------------+
|  1 | qiwsir   | 123123   | qiwsir@gmail.com |
|  2 | python   | 123456   | python@gmail.com |
+----+----------+----------+------------------+
2 rows in set (0.00 sec)

good,very good。果然如此。这就如同编写一个文本一样,将文字写到文本上,并不等于文字已经保留在文本文件中了,必须执行"CTRL-S"才能保存。也就是在通过python操作数据库的时候,以"execute()"执行各种sql语句之后,要让已经执行的效果保存,必须运行"commit()",还要提醒,这个属性是"MySQLdb.connect()"实例的。

再尝试一下插入多条的那个命令"executemany(query,args)".

>>> cur.executemany("insert into users (username,password,email) values (%s,%s,%s)",(("google","111222","g@gmail.com"),("facebook","222333","f@face.book"),("github","333444","git@hub.com"),("docker","444555","doc@ker.com")))
4L
>>> conn.commit()

到"mysql>"里面看结果:

mysql> select * from users;
+----+----------+----------+------------------+
| id | username | password | email            |
+----+----------+----------+------------------+
|  1 | qiwsir   | 123123   | qiwsir@gmail.com |
|  2 | python   | 123456   | python@gmail.com |
|  3 | google   | 111222   | g@gmail.com      |
|  4 | facebook | 222333   | f@face.book      |
|  5 | github   | 333444   | git@hub.com      |
|  6 | docker   | 444555   | doc@ker.com      |
+----+----------+----------+------------------+
6 rows in set (0.00 sec)

成功插入了多条记录。特别请列位注意的是,在"executemany(query,args)"中,query还是一条sql语句,但是args这时候是一个tuple,这个tuple里面的元素也是tuple,每个tuple分别对应sql语句中的字段列表。这句话其实被执行多次。只不过执行过程不显示给我们看罢了。

已经会插入了,然后就可以有更多动作。且看下面吧。

#用Python操作数据库(2)

回顾一下已有的战果:(1)连接数据库;(2)建立指针;(3)通过指针插入记录;(4)提交将插入结果保存到数据库。在交互模式中,先温故,再知新。

>>> #导入模块
>>> import MySQLdb>>> #连接数据库
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123123",db="qiwsirtest",port=3036,charset="utf8")>>> #建立指针
>>> cur = conn.cursor()>>> #插入记录
>>> cur.execute("insert into users (username,password,email) values (%s,%s,%s)",("老齐","9988","qiwsir@gmail.com"))
1L>>> #提交保存
>>> conn.commit()

如果看官跟我似的,有点强迫症,总是想我得看到数据中有了,才放芳心呀。那就在进入到数据库,看看。

mysql> select * from users;+----+----------+----------+------------------+| id | username | password | email            |+----+----------+----------+------------------+|  1 | qiwsir   | 123123   | qiwsir@gmail.com ||  2 | python   | 123456   | python@gmail.com ||  3 | google   | 111222   | g@gmail.com      ||  4 | facebook | 222333   | f@face.book      ||  5 | github   | 333444   | git@hub.com      ||  6 | docker   | 444555   | doc@ker.com      ||  7 | 老齐     | 9988     | qiwsir@gmail.com |+----+----------+----------+------------------+7 rows in set (0.00 sec)

刚才温故的时候,插入的那条记录也赫然在目。不过这里特别提醒看官,我在前面建立这个数据库和数据表的时候,就已经设定好了字符编码为utf8,所以,在现在看到的查询结果中,可以显示汉字。否则,就看到的是一堆你不懂的码子了。如果看官遇到,请不要慌张,只需要修改字符编码即可。怎么改?请google。网上很多。

温故结束,开始知新。

##查询数据

在前面操作的基础上,如果要从数据库中查询数据,当然也可以用指针来操作了。

>>> cur.execute("select * from users")
7L

这说明从users表汇总查询出来了7条记录。但是,这似乎有点不友好,告诉我7条记录查出来了,但是在哪里呢,看前面在'mysql>'下操作查询命令的时候,一下就把7条记录列出来了。怎么显示python在这里的查询结果呢?

原来,在指针实例中,还要用这样的方法,才能实现上述想法:

  • fetchall(self):接收全部的返回结果行.
  • fetchmany(size=None):接收size条返回结果行.如果size的值大于返回的结果行的数量,则会返回cursor.arraysize条数据.
  • fetchone():返回一条结果行.
  • scroll(value, mode='relative'):移动指针到某一行.如果mode='relative',则表示从当前所在行移动value条,如果mode='absolute',则表示从结果集的第一行移动value条.

按照这些规则,尝试:

>>> cur.execute("select * from users")
7L
>>> lines = cur.fetchall()

到这里,还没有看到什么,其实已经将查询到的记录(把他们看做对象)赋值给变量lines了。如果要把它们显示出来,就要用到曾经学习过的循环语句了。

>>> for line in lines:
...     print line
...
(1L, u'qiwsir', u'123123', u'qiwsir@gmail.com')
(2L, u'python', u'123456', u'python@gmail.com')
(3L, u'google', u'111222', u'g@gmail.com')
(4L, u'facebook', u'222333', u'f@face.book')
(5L, u'github', u'333444', u'git@hub.com')
(6L, u'docker', u'444555', u'doc@ker.com')
(7L, u'\u8001\u9f50', u'9988', u'qiwsir@gmail.com')

很好。果然是逐条显示出来了。列位注意,第七条中的u'\u8001\u95f5',这里是汉字,只不过由于我的shell不能显示罢了,不必惊慌,不必搭理它。

只想查出第一条,可以吗?当然可以!看下面的:

>>> cur.execute("select * from users where id=1")
1L
>>> line_first = cur.fetchone()     #只返回一条
>>> print line_first
(1L, u'qiwsir', u'123123', u'qiwsir@gmail.com')

为了对上述过程了解深入,做下面实验:

>>> cur.execute("select * from users")
7L
>>> print cur.fetchall()
((1L, u'qiwsir', u'123123', u'qiwsir@gmail.com'), (2L, u'python', u'123456', u'python@gmail.com'), (3L, u'google', u'111222', u'g@gmail.com'), (4L, u'facebook', u'222333', u'f@face.book'), (5L, u'github', u'333444', u'git@hub.com'), (6L, u'docker', u'444555', u'doc@ker.com'), (7L, u'\u8001\u9f50', u'9988', u'qiwsir@gmail.com'))

原来,用cur.execute()从数据库查询出来的东西,被“保存在了cur所能找到的某个地方”,要找出这些被保存的东西,需要用cur.fetchall()(或者fechone等),并且找出来之后,做为对象存在。从上面的实验探讨发现,被保存的对象是一个tuple中,里面的每个元素,都是一个一个的tuple。因此,用for循环就可以一个一个拿出来了。

看官是否理解其内涵了?

接着看,还有神奇的呢。

接着上面的操作,再打印一遍

>>> print cur.fetchall()
()

晕了!怎么什么是空?不是说做为对象已经存在了内存中了吗?难道这个内存中的对象是一次有效吗?

不要着急。

通过指针找出来的对象,在读取的时候有一个特点,就是那个指针会移动。在第一次操作了print cur.fetchall()后,因为是将所有的都打印出来,指针就要从第一条移动到最后一条。当print结束之后,指针已经在最后一条的后面了。接下来如果再次打印,就空了,最后一条后面没有东西了。

下面还要实验,检验上面所说:

>>> cur.execute('select * from users')
7L
>>> print cur.fetchone()
(1L, u'qiwsir', u'123123', u'qiwsir@gmail.com')
>>> print cur.fetchone()
(2L, u'python', u'123456', u'python@gmail.com')
>>> print cur.fetchone()
(3L, u'google', u'111222', u'g@gmail.com')

这次我不一次全部打印出来了,而是一次打印一条,看官可以从结果中看出来,果然那个指针在一条一条向下移动呢。注意,我在这次实验中,是重新运行了查询语句。

那么,既然在操作存储在内存中的对象时候,指针会移动,能不能让指针向上移动,或者移动到指定位置呢?这就是那个scroll()

>>> cur.scroll(1)
>>> print cur.fetchone()
(5L, u'github', u'333444', u'git@hub.com')
>>> cur.scroll(-2)
>>> print cur.fetchone()
(4L, u'facebook', u'222333', u'f@face.book')

果然,这个函数能够移动指针,不过请仔细观察,上面的方式是让指针相对与当前位置向上或者向下移动。即:

cur.scroll(n),或者,cur.scroll(n,"relative"):意思是相对当前位置向上或者向下移动,n为正数,表示向下(向前),n为负数,表示向上(向后)

还有一种方式,可以实现“绝对”移动,不是“相对”移动:增加一个参数"absolute"

特别提醒看官注意的是,在python中,序列对象是的顺序是从0开始的。

>>> cur.scroll(2,"absolute")    #回到序号是2,但指向第三条
>>> print cur.fetchone()        #打印,果然是
(3L, u'google', u'111222', u'g@gmail.com')>>> cur.scroll(1,"absolute")
>>> print cur.fetchone()
(2L, u'python', u'123456', u'python@gmail.com')>>> cur.scroll(0,"absolute")    #回到序号是0,即指向tuple的第一条
>>> print cur.fetchone()
(1L, u'qiwsir', u'123123', u'qiwsir@gmail.com')

至此,已经熟悉了cur.fetchall()和cur.fetchone()以及cur.scroll()几个方法,还有另外一个,接这上边的操作,也就是指针在序号是1的位置,指向了tuple的第二条

>>> cur.fetchmany(3)
((2L, u'python', u'123456', u'python@gmail.com'), (3L, u'google', u'111222', u'g@gmail.com'), (4L, u'facebook', u'222333', u'f@face.book'))

上面这个操作,就是实现了从当前位置(指针指向tuple的序号为1的位置,即第二条记录)开始,含当前位置,向下列出3条记录。

读取数据,好像有点啰嗦呀。细细琢磨,还是有道理的。你觉得呢?

不过,python总是能够为我们着想的,它的指针提供了一个参数,可以实现将读取到的数据变成字典形式,这样就提供了另外一种读取方式了。

>>> cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
>>> cur.execute("select * from users")
7L
>>> cur.fetchall()
({'username': u'qiwsir', 'password': u'123123', 'id': 1L, 'email': u'qiwsir@gmail.com'}, {'username': u'mypython', 'password': u'123456', 'id': 2L, 'email': u'python@gmail.com'}, {'username': u'google', 'password': u'111222', 'id': 3L, 'email': u'g@gmail.com'}, {'username': u'facebook', 'password': u'222333', 'id': 4L, 'email': u'f@face.book'}, {'username': u'github', 'password': u'333444', 'id': 5L, 'email': u'git@hub.com'}, {'username': u'docker', 'password': u'444555', 'id': 6L, 'email': u'doc@ker.com'}, {'username': u'\u8001\u9f50', 'password': u'9988', 'id': 7L, 'email': u'qiwsir@gmail.com'})

这样,在元组里面的元素就是一个一个字典。可以这样来操作这个对象:

>>> cur.scroll(0,"absolute")
>>> for line in cur.fetchall():
...     print line["username"]
...
qiwsir
mypython
google
facebook
github
docker
老齐

根据字典对象的特点来读取了“键-值”。

##更新数据

经过前面的操作,这个就比较简单了,不过需要提醒的是,如果更新完毕,和插入数据一样,都需要commit()来提交保存。

>>> cur.execute("update users set username=%s where id=2",("mypython"))
1L
>>> cur.execute("select * from users where id=2")
1L
>>> cur.fetchone()
(2L, u'mypython', u'123456', u'python@gmail.com')

从操作中看出来了,已经将数据库中第二条的用户名修改为mypython了,用的就是update语句。

不过,要真的实现在数据库中更新,还要运行:

>>> conn.commit()

这就大事完吉了。

#用Python操作数据库(3)

通过python操作数据库的行为,除了能够完成前面两讲中的操作之外(当然,那是比较常用的),其实任何对数据库进行的操作,都能够通过python-mysqldb来实现。

##建立数据库

在《用python操作数据库(1)》中,我是通过mysql>写SQL语句,建立了一个名字叫做qiwsirtest的数据库,然后用下面的方式跟这个数据库连接

>>> import MySQLdb
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123123",db="qiwsirtest",charset="utf8")

在上面的连接中,参数db="qiwsirtest"其实可以省略,如果省略,就是没有跟任何具体的数据库连接,只是连接了mysql。

>>> import MySQLdb
>>> conn = MySQLdb.connect("localhost","root","123123",port=3306,charset="utf8")

这种连接没有指定具体数据库,接下来就可以用类似mysql>交互模式下的方式进行操作。

>>> conn.select_db("qiwsirtest")
>>> cur = conn.cursor()
>>> cur.execute("select * from users")
7L
>>> cur.fetchall()
((1L, u'qiwsir', u'123123', u'qiwsir@gmail.com'), (2L, u'mypython', u'123456', u'python@gmail.com'), (3L, u'google', u'111222', u'g@gmail.com'), (4L, u'facebook', u'222333', u'f@face.book'), (5L, u'github', u'333444', u'git@hub.com'), (6L, u'docker', u'444555', u'doc@ker.com'), (7L, u'\u8001\u9f50', u'9988', u'qiwsir@gmail.com'))

conn.select_db()选择要操作的数据库,然后通过指针就可以操作这个数据库了。其它的操作跟前两讲一样了。

如果不选数据库,而是要新建一个数据库,如何操作?

>>> cur = conn.cursor()
>>> cur.execute("create database newtest")
1L

建立数据库之后,就可以选择这个数据库,然后在这个数据库中建立一个数据表。

>>> cur.execute("create table newusers (id int(2) primary key auto_increment, username varchar(20), age int(2), email text)")
0L

括号里面是引号,引号里面就是创建数据表的语句,看官一定是熟悉的。这样就在newtest这个数据库中创建了一个名为newusers的表

>>> cur.execute("show tables")
1L
>>> cur.fetchall()
((u'newusers',),)

这是查看表的方式。当然,看官可以在mysql>交互模式下查看是不是存在这个表。如下:

mysql> use newtest;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show tables;
+-------------------+
| Tables_in_newtest |
+-------------------+
| newusers          |
+-------------------+
1 row in set (0.00 sec)mysql> desc newusers;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(2)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(20) | YES  |     | NULL    |                |
| age      | int(2)      | YES  |     | NULL    |                |
| email    | text        | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

以上就通过python-mysqldb实现了对数据库和表的建立。

当然,能建就能删除。看官可以自行尝试,在这里就不赘述,原理就是在cur.execute()中写SQL语句。

##关闭一切

当进行完有关数据操作之后,最后要做的就是关闭游标(指针)和连接。用如下命令实现:

>>> cur.close()
>>> conn.close()

注意关闭顺序,和打开的顺序相反。

为什么要关闭?这个问题有点那个了。你把房子里面都收拾好了,如果离开房子,不关门吗?不要以为自己生活在那个理想社会。树欲静而风不止,小偷在行动。更何况,如果不关闭,服务器的内容总塞着那些东西而没有释放,早晚就满了。所以,必须关闭。必须的。

##关于乱码问题

这个问题是编写web时常常困扰程序员的问题,乱码的本质来自于编码格式的设置混乱。所以,要特别提醒诸位注意。在用python-mysqldb的时候,为了放置乱码,可以做如下统一设置:

  1. Python文件设置编码 utf-8(文件前面加上 #encoding=utf-8)
  2. MySQL数据库charset=utf8(数据库的设置方法,可以网上搜索)
  3. Python连接MySQL是加上参数 charset=utf8(在前面教程中都这么演示了,很重要)
  4. 设置Python的默认编码为 utf-8 (sys.setdefaultencoding(utf-8),这个后面会讲述)

代码示例:

#encoding=utf-8import sys
import MySQLdbreload(sys)
sys.setdefaultencoding('utf-8')db=MySQLdb.connect(user='root',charset='utf8')

MySQL的配置文件设置也必须配置成utf8 设置 MySQL 的 my.cnf 文件,在 [client]/[mysqld]部分都设置默认的字符集(通常在/etc/mysql/my.cnf):

[client] default-character-set = utf8
[mysqld] default-character-set = utf8

windows操作系统请看官自己google。

connect to db by mysqldb-python and use it相关推荐

  1. 登陆后台时,弹出Cann't connect to DB!

    烈火网(LieHuo.Net)教程 用帝国CMS建的网站,最近经常出现 Cann't connect to DB! 不定时的出现 Cann't connect to DB! mysql重新安装了也不管 ...

  2. 帝国cms后台登陆显示Cann‘t connect to DB 解决方法

    帝国cms后台登录显示Cann't connect to DB!是什么原因呢?想必很多的小伙伴在网站搬家或者是上传空间服务器都会遇见这个问题吧!出现这段提示是什么原因呢?很多小白就困惑了,这到底什么意 ...

  3. cann't connect to db! mysql!,解决SQL Error: Can't connect to MySQL server on错误

    解决SQL Error: Can't connect to MySQL server on错误 文章来源:传奇帮手游 发布时间:2020-12-02 文章性质:原创文章 今天帮主在群里看到有一个兄弟在 ...

  4. 安装mysqldb python接口时找不到mysql_config

    我正在尝试使Python脚本在通过ssh连接到的Linux服务器上运行. 该脚本使用mysqldb. 我有我需要的所有其他组件,但是当我尝试通过setuptools安装mySQLdb时,如下所示: p ...

  5. mysqldb mysql config,安装mysqldb python界面时找不到mysql_config

    mySQLdb是一个用于mysql的python界面,但它不是mysql本身. 显然mySQLdb需要命令"mysql_config",所以你需要先安装. 你能否确认你是否通过从s ...

  6. cannt connect to db!_分贝db以及在语音的用途

    本文主要通过简明扼要的方式介绍db,db关键性质,如何计算,以及信噪比和如何控制信噪比等,本文是学习笔记,有自己的理解和代码,也有参考一些大牛的文章,链接也放在了下方,如有侵权立即删除.推荐阅读什么是 ...

  7. Python全栈5 - Web开发入门

    5.Python Web开发 1Web 开发介绍 1-1 Web 开发概述 C/S B/S – web开发 访问网站的过程: 静态网站 动态网站 – 网站由于用户的请求不同,而呈现出不同的的结果 MV ...

  8. Python MySQL(MySQLdb)

    Python MySQL(MySQLdb) Python标准的数据库接口的Python DB-API(包括Python操作MySQL).大多数Python数据库接口坚持这个标准. Python标准的数 ...

  9. python db读写实践

    目录 1 读db 2 写db 3 读取GeomWGS84字段 1 读db import sqlite3def ReadDB(path: str):conn = sqlite3.connect(path ...

最新文章

  1. MoviePy - 中文文档4-MoviePy实战案例-把多个clip放置在一个画面中(超美)
  2. 王者荣耀s22服务器未响应是什么意思,王者荣耀s22资源包升级失败 s22解析包出现问题解决方法...
  3. 大型系统OA--技术
  4. 动态内存管理:malloc和free以及new和delete的联系与区别
  5. git 安装目录与服务的暂停与启动
  6. redmine 无法登录 mysql 服务器_Redmine 数据库连接错误
  7. C++ 拷贝构造函数与赋值构造函数调用时机初步01
  8. oracle 数据操作指令,ORACLE数据操作命令
  9. PCL编程笔记——Assertion `px != 0' failed.
  10. 优秀的程序员是这样的
  11. 利用console.time优化js代码
  12. thymeleaf 的hello world
  13. 五胡十六国、东晋南北朝这280年历史,你知道多少?5000字带你看个清楚明白
  14. 【中科三方】什么是云解析DNS?云解析DNS有必要购买吗?
  15. 北京亿阳信通java笔试题_亿阳信通笔试
  16. 在龙芯3A5000上测试SPEC CPU 2006
  17. 使用Matlab进行符号定积分运算
  18. 机器人(含自动驾驶汽车)成本和电脑手机相比有哪些差异化
  19. CososCreator (Android)-AppLovin MAX 广告聚合平台接入+Firebase统计
  20. 颜色在计算机中的存储和显示详解

热门文章

  1. 设置eclipse护眼背景色---豆沙绿
  2. 射频功率放大器在超声导波技术管道损伤检测研究中的应用
  3. 教大家如何选择合适的CMMI认证机构?
  4. python二元函数图像在线绘制_Python绘制二元函数曲面
  5. 【计算机网络】抓取路由器包
  6. [简易]中英文混合排序
  7. 全球100家杂志网站(转)
  8. sox 获取wav文件的时长
  9. Vue2开发购物街项目总结
  10. 自媒体生存现状调查:僧多粥少,集体焦虑