zoukankan      html  css  js  c++  java
  • python MySQLdb安装和使用

    MySQLdb是python的一个标准的连接和操纵mysql的模块。

    下载地址;

    https://pypi.python.org/pypi/MySQL-python/1.2.4#downloads

    sourceforge地址:

    http://sourceforge.net/projects/mysql-python/

    说一下版本问题,去上面的网址可以看到,有2个版本MySQLdb1,MySQLdb2,默认下载的是MySqLdb2,可是到了第二版,作者又新开了一个项目叫moist

    https://github.com/farcepest/moist

    就是前面版本的升级,不知道作者为什么要新开一个项目。查看作者MySQLdb2的readme:

    This is the legacy (1.x) version of MySQLdb. While it is still being maintained, there will not be a lot of new feature development.

    TODO

    • A bugfix 1.2.4 release
    • A 1.3.0 release that will support Python 2.7-3.3

    The 2.0 version is being renamed moist and lives at https://github.com/farcepest/moist

    mysql python的说明文档:

    http://sourceforge.net/p/mysql-python/mysqldb-2/ci/default/tree/doc/MySQLdb.txt

    *************************

    我用源代码编译安装时报错,于是直接下载exe文件安装就成功了。

    通过pip安装

    $pip install MySQL-python 

    我最初使用这种形式安装的,不知道怎么回事,安装成功了,但导入包import MySQLdb总是说找不到。

    安装完成,到你的python安装目录下的site-packages目录里检查以下文件是否存在,如果存在即代表安装成功了
    Linux:MySQL_python-1.2.3c1-py2.6-linux-i686.egg
    Mac OS X:MySQL_python-1.2.3c1-py2.6-macosx-10.4-x86_64.egg

    import MysqlDB

    报错:mysql mportError: DLL load failed: %1 不是有效的 Win32 应用程序

    操作系统:win7 64位,安装mysqldb 后提示:ImportError DLL load failed: %1 不是有效的 Win32 应用程序,是由于安装的32位的 MySql-python-1.2.3.win32-py2.exe,,只要改成64位版本的就可以了。

    怎么看安装的模块是多少位?

    MySQL-python-1.2.3.win-amd64-py2.7.exe

    MySQL-python-1.2.5.win32-py2.7.exe

    介个就很明显了。

    在官网:http://sourceforge.net/projects/mysql-python/ 没有64的提供。

    经过搜索,下载到了

    MySQL-python-1.2.5.win-amd64-py2.7.exe

     

     

    参考之前的文章:

    Python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序。

    select:

    import MySQLdb
    conn = MySQLdb.connect(host='127.0.0.1', port=3306,user='root', passwd='longforfreedom',db='python')
    cursor = conn.cursor()
    count = cursor.execute('select * from test')
    print '总共有 %s 条记录',count
    #获取一条记录,每条记录做为一个元组返回
    print "只获取一条记录:"
    result = cursor.fetchone();
    print result
    #print 'ID: %s info: %s' % (result[0],result[1])
    print 'ID: %s info: %s' % result
    #获取5条记录,注意由于之前执行有了fetchone(),所以游标已经指到第二条记录了,也就是从第二条开始的所有记录
    print "只获取5条记录:"
    results = cursor.fetchmany(5)
    for r in results:
    print r
    print "获取所有结果:"
    #重置游标位置,0,为偏移量,mode=absolute | relative,默认为relative,
    cursor.scroll(0,mode='absolute')
    #获取所有结果
    results = cursor.fetchall()
    for r in results:
    print r
    conn.close()

    最开始我连接不上:报错

    _mysql_exceptions.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' (10061)")

    conn = MySQLdb.connect(host='localhost', port=3306,user='root', passwd='longforfreedom',db='python')

    import MySQLdb
    try:
        conn=MySQLdb.connect(host='127.0.0.1',user='root',passwd='admin',db='mysql',port=3306)
        cur=conn.cursor()
        #cur.execute('select * from user')
        cur.execute('select version()')
        data = cur.fetchone()
        print "Databases version: %s " %  data
        cur.close()
        conn.close()
    except MySQLdb.Error,e:
         print "Mysql Error %d: %s" % (e.args[0], e.args[1])
     

    把loclhoast改为ip地址就可以了。具体原因不清楚。

    创建数据库:

    import MySQLdb
    #建立和数据库系统的连接
    conn = MySQLdb.connect(host='localhost', user='root',passwd='longforfreedom')
    #获取操作游标
    cursor = conn.cursor()
    #执行SQL,创建一个数据库.
    cursor.execute("""create database python """)
    #关闭连接,释放资源
    cursor.close();

    创建数据库,创建表,插入数据,插入多条数据

    import MySQLdb
    #建立和数据库系统的连接
    conn = MySQLdb.connect(host='localhost', user='root',passwd='longforfreedom')
    #获取操作游标
    cursor = conn.cursor()
    #执行SQL,创建一个数据库.
    cursor.execute("""create database if not exists python""")
    #选择数据库
    conn.select_db('python');
    #执行SQL,创建一个数据表.
    cursor.execute("""create table test(id int, info varchar(100)) """)
    value = [1,"inserted ?"];
    #插入一条记录
    cursor.execute("insert into test values(%s,%s)",value);
    values=[]
    #生成插入参数值
    for i in range(20):
    values.append((i,'Hello mysqldb, I am recoder ' + str(i)))
    #插入多条记录
    cursor.executemany("""insert into test values(%s,%s) """,values);
    #关闭连接,释放资源
    cursor.close();

    我现在插入有点问题,插入不了。

    摘自doc上的话:

    To perform a query, you first need a cursor, and then you can execute
    queries on it::
     
    c=db.cursor()
    max_price=5
    c.execute("""SELECT spam, eggs, sausage FROM breakfast
    WHERE price < %s""", (max_price,)) 注意,后面一个参数为tuple
     
    In this example, ``max_price=5`` Why, then, use ``%s`` in the
    string? Because MySQLdb will convert it to a SQL literal value, which
    is the string '5'. When it's finished, the query will actually say,
    "...WHERE price < 5".
     
    Why the tuple? Because the DB API requires you to pass in any
    parameters as a sequence. Due to the design of the parser, (max_price)
    is interpreted as using algebraic grouping and simply as max_price and
    not a tuple. Adding a comma, i.e. (max_price,) forces it to make a
    tuple.
     
    And now, the results::
     
    >>> c.fetchone()
    (3L, 2L, 0L)
     
    Quite unlike the ``_mysql`` example, this returns a single tuple,
    which is the row, and the values are properly converted by default...
    except... What's with the L's?
     为什么后面有L,long integers?
    As mentioned earlier, while MySQL's INTEGER column translates
    perfectly into a Python integer, UNSIGNED INTEGER could overflow, so
    these values are converted to Python long integers instead.
     
    If you wanted more rows, you could use ``c.fetchmany(n)`` or
    ``c.fetchall()``. These do exactly what you think they do. On
    ``c.fetchmany(n)``, the ``n`` is optional and defaults to
    ``c.arraysize``, which is normally 1. Both of these methods return a
    sequence of rows, or an empty sequence if there are no more rows. If
    you use a weird cursor class, the rows themselves might not be tuples.
     
    Note that in contrast to the above, ``c.fetchone()`` returns ``None``
    when there are no more rows to fetch.
     
    The only other method you are very likely to use is when you have to
    do a multi-row insert::
     
    c.executemany(
    """INSERT INTO breakfast (name, spam, eggs, sausage, price)
    VALUES (%s, %s, %s, %s, %s)""",
    [
    ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
    ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
    ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
    ] )
     
    Here we are inserting three rows of five values. Notice that there is
    a mix of types (strings, ints, floats) though we still only use
    ``%s``. And also note that we only included format strings for one
    row. MySQLdb picks those out and duplicates them for each row.
     
    其实 还可以这么写:
    value=('单人间',1,5)
    cursor.execute("insert into room (roomType,hotelId,roomNum) values(%s,%s,%s)",value)
    利用python百分号的威力,可以写成:

    value1='单人间'
    value2=5
    value3=5

    cursor.execute("insert into room (roomType,hotelId,roomNum) values('%s',%d,%d)" % (value1,value2,value3) )

    insertId=conn.insert_id()
    affectedRows=conn.affected_rows()
    conn.commit()

     这里主要利用%后面的会替换前面的占位符。
    上面的输出:

    14 insert id
    1 affected rows。

    这是2个很重要的方法。

    一直困扰我的问题:下面的代码:
    import MySQLdb
    
    def dbinsert():
        conn=MySQLdb.connect(host='127.0.0.1',port=3306,user='root',passwd='sm159357',db='hotelbookown')
    
        cursor = conn.cursor()
        cursor.execute("select * from user")
        results=cursor.fetchall()
        for r in results:
            print r
        value=('user12','user12')
        #插入一条记录
        cursor.execute("insert into user (username,password) values(%s,%s)",value)
         

    我确实 可以运行,也不报错,但是数据库就是没有插入记录,很郁闷。在网上看到帖子说要在execute后加个

    conn.commit()就可以了,果不其然,确实可以。

    解决中午插入乱码

    在文件前面加coding=utf-8

    连接时:

    conn=MySQLdb.connect(host='127.0.0.1',port=3306,user='root',passwd='sm159357',db='hotelbookown',charset='utf8')

    中文插入时应该是这样

    a=u'中文

    如果是a=’中文‘则错误。

    插入多条数据(带有int型的)都用%s 会自动转换的。

     valueArr=[
            ('单人间',1,5),
            ('单人间',2,5),
            ('双人间',3,5)
            ]
        cursor.executemany("insert into room (roomType,hotelId,roomNum) values(%s,%s,%s)",valueArr)
        conn.commit()

    关闭方法,

    cursor.close()

    conn.close()

    很奇怪我为什么delet无效,原因在于没有用

     conn.commit()


    测试增删改查操作
    import MySQLdb
    
    conn = MySQLdb.connect(
                           host = '127.0.0.1',
                           port = 3306,
                           user = 'root',
                           passwd = '142857',
                           db = 'user',
                           charset = 'utf8'
                           )
    
    cursor = conn.cursor()
    sql_insert = 'insert into user_table(`id`,`name`) values(10,"name10")'
    sql_update = 'update user_table set `name`="name_07" where id =7'
    sql_delete = "delete from user_table where id<3 "
    
    
    try:
        cursor.execute(sql_insert)
        print cursor.rowcount
        
        cursor.execute(sql_update)
        print cursor.rowcount
        
        cursor.execute(sql_delete)
        print cursor.rowcount
        
        conn.commit()
    except Exception as e:
        print e
        conn.rollback()
    
    cursor.close()
    conn.close()

    这里特别要注意的是sql语句使用execute()方法执行后,要使用commit()方法提交处理,当事务失败后,要调用rollback()方法进行事务的回滚。注意尽量避免使用不支持事务的存储引擎。

    使用python操作数据库模拟银行转账的功能

    import sys
    import MySQLdb
    
    class TransferMoney():
        def __init__(self,conn):
            self.conn = conn
        
    
        def check_acct_available(self, acctid):
            cursor = self.conn.cursor()
            try:
                sql = 'select * from account where acctid=%s' % acctid
                cursor.execute(sql)
                print 'check_acct_available:' + sql
                rs = cursor.fetchall()
                if len(rs) != 1:
                    raise Exception("账号%s不存在" % acctid)
            finally:
                cursor.close()
        
        def has_enough_money(self, acctid, money):
            cursor = self.conn.cursor()
            try:
                sql = 'select * from account where acctid=%s and money > %s' % (acctid,money)
                cursor.execute(sql)
                print 'has_enough_money:' + sql
                rs = cursor.fetchall()
                if len(rs) != 1:
                    raise Exception("账号%s没有足够的钱" % acctid)
            finally:
                cursor.close()
        
        
        def reduce_money(self, acctid, money):
            cursor = self.conn.cursor()
            try:
                sql = 'update account set money=money-%s where acctid=%s' % (money,acctid)
                cursor.execute(sql)
                print 'reduce_money:' + sql
                if cursor.rowcount != 1:
                    raise Exception("账号%s减款失败" % acctid)
            finally:
                cursor.close()
        
        
        def add_money(self, acctid, money):
            cursor = self.conn.cursor()
            try:
                sql = 'update account set money=money+%s where acctid=%s' % (money,acctid)
                cursor.execute(sql)
                print 'add_money:' + sql
                if cursor.rowcount != 1:
                    raise Exception("账号%s加款失败" % acctid)
            finally:
                cursor.close()
        
        
        def transfer(self,source_acctid,target_acctid,money):
            try:
                self.check_acct_available(source_acctid)
                self.check_acct_available(target_acctid)
                self.has_enough_money(source_acctid,money)
                self.reduce_money(source_acctid,money)
                self.add_money(target_acctid,money)
                self.conn.commit()
            except Exception as e:
                self.conn.rollback()
                raise e
            
            
    if __name__ == "__main__":
        source_acctid = sys.argv[1]
        target_acctid = sys.argv[2]
        money = sys.argv[3]
        print source_acctid,' ',target_acctid,' ',money
        conn = MySQLdb.connect(host='127.0.0.1',port = 3306,user = 'root',passwd='142857',db ='user',charset = 'utf8')
        tr_money = TransferMoney(conn)
        try:
            tr_money.transfer(source_acctid,target_acctid,money)
        except Exception as e:
            print u'出现问题',e
        finally:
            conn.close()  
    View Code

    账户 11 余额为110元

    账户 12 余额为10元

    执行12 11 100意为账户12转给账户11 100元,则转账失败

    转账失败那么11的钱没增加,12的钱也不能少,回到数据的初始状态,这就是事务的回滚。

    当账户11转给12账户100元时,可以完成操作,转账成功。回到数据库刷新可以看到11的钱少了100元,12的钱增加了100元。

    参考:http://blog.sina.com.cn/s/blog_7cc54c730101hal3.html

    保证输出没有乱码:

      我用了下面几个措施,保证MySQL的输出没有乱麻:
       1 Python文件设置编码 utf-8 (文件前面加上 #encoding=utf-8)
       2 MySQL数据库charset=utf-8
       3 Python连接MySQL是加上参数 charset=utf8
       4 设置Python的默认编码为 utf-8 (sys.setdefaultencoding(utf-8)
      mysql_test.py  

    #encoding=utf-8
      import sys
      import MySQLdb
      
      reload(sys)
      sys.setdefaultencoding('utf-8')
      
      db=MySQLdb.connect(user='root',charset='utf8')
      cur=db.cursor()
      cur.execute('use mydb')
      cur.execute('select * from mytb limit 100')
      
      f=file("/home/user/work/tem.txt",'w')
      
      for i in cur.fetchall():
       f.write(str(i))
       f.write(" ")
      
      f.close()
      cur.close()

    上面是linux上的脚本,windows下运行正常!
      
      注:MySQL的配置文件设置也必须配置成utf8
      
      设置 MySQL 的 my.cnf 文件,在 [client]/[mysqld]部分都设置默认的字符集(通常在/etc/mysql/my.cnf):
      [client]
      default-character-set = utf8
      [mysqld]
      default-character-set = utf8

     
    参考:
    http://blog.chinaunix.net/uid-8487640-id-3183185.html
    http://www.iteye.com/topic/573092
    http://hi.baidu.com/onekunp/item/80771e3fd63905be124b1440
    http://www.linuxidc.com/Linux/2012-05/60353.htm

    遇到的问题:

    self.cursor=self.cursor.execute("select id from urllist where url='%s' " % url )
    res=self.cursor.fetchone()

    错误:

    AttributeError: 'long' object has no attribute 'fetchone'

    其实,execute select id 返回的是类似(1L,)这样的元祖。

    为什么上面错误,因为execute返回的select的数目count,

    不用赋值。应该是这样:

    self.cursor.execute("select id from urllist where url='%s' " % url )
    res=self.cursor.fetchone()

    centos安装pythondb

    步骤如下:

    #安装MySQLdb
    wget https://pypi.python.org/packages/source/M/MySQL-python/MySQL-python-1.2.5.zip#md5=654f75b302db6ed8dc5a898c625e030c
    unzip MySQL-python-1.2.5.zip
    cd MySQL-python-1.2.5
    chmod -R 775 *
    python setup.py build

    python setup.py install

    mysql-python安装时EnvironmentError: mysql_config not found

    就是要找到mysql_config这个可执行文件

    只要原因是没有安装:libmysqlclient-dev

    sudo apt-get install libmysqlclient-dev

    找到mysql_config文件的路径

    sudo updatedb
    locate mysql_config

    mysql_config的位置为:/usr/bin/mysql_config

    在mysql-python源码包下找到:setup_posix.py 文件,然后找到文件中的 mysql_config.path 将其值改为:/usr/bin/mysql_config,然后 sudo python setup.py install ,就ok了

    _LINUX -DUNIV_LINUX
    _mysql.c:29:20: fatal error: Python.h: No such file or directory
    #include "Python.h"
    ^

    安装:

     yum install python-devel .

  • 相关阅读:
    设置WebSphere字符集参数
    防SQL注入
    改变radio/checkbox默认样式
    数据完整性约束错误
    Java项目多数据源配置
    No row with the given identifier exists:错误另解
    ICTCLAS20160405分词系统调试过程
    centos7 忘记root密码
    java之Junit
    javaweb之登录
  • 原文地址:https://www.cnblogs.com/youxin/p/3159874.html
Copyright © 2011-2022 走看看