2019-01-14 15:09:54 cpongo6 阅读数 26
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    12050 人正在学习 去看看 尹成


Python连接MySQL


http://www.runoob.com/python3/python-mysql-connector.html


由于 MySQL 服务器以独立的进程运行,并通过网络对外服务,所以,需要支持 Python MySQL 驱动来连接到 MySQL 服务器。 MySQL 官方提供了 mysql-connector-python 驱动,但是安装的时候需要给 pip 命令加上参数 --allow-external

$ pip install mysql-connector-python --allow-external mysql-connector-python

如果上面的命令安装失败,可以试试另一个驱动:

$ pip install mysql-connector

Python 连接到 MySQL 数据库示例:

# 导入MySQL驱动:
import mysql.connector
# 注意把password设为root口令,需要提前创建好lhrdb数据库
conn = mysql.connector.connect(user='root', password='lhr', database='lhrdb',host='127.0.0.1',port=3306)
cursor = conn.cursor()
# 创建user表:
cursor.execute('drop table if exists user')
cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
# 插入一行记录,注意MySQL的占位符是%s:
cursor.execute('insert into user (id, name) values (%s, %s)', ['1', 'xiaomaimiao'])
cursor.execute('insert into user (id, name) values (%s, %s)', ['2', 'xiaotinger'])
print(cursor.rowcount)
# 提交事务:
conn.commit()
cursor.close()
# 运行查询:
cursor = conn.cursor()
cursor.execute('select * from user where id = %s', ('1',))
values = cursor.fetchall()
print(values)
# 关闭Cursor和Connection:
cursor.close()
conn.close()
运行结果:
1
[('1', 'xiaomaimiao')]
在MySQL中查询:
mysql> select * from user;
+----+-------------+
| id | name        |
+----+-------------+
| 1  | xiaomaimiao |
| 2  | xiaotinger  |
+----+-------------+
2 rows in set (0.00 sec)
需要注意的是:
l 执行INSERT等操作后要调用commit()提交事务;
l MySQL的SQL占位符是%s。


真题1、 Python 如何批量往 MySQL 数据库插入数据?

答案:批量插入使用 executemany() 方法,该方法的第二个参数是一个元组列表,包含了需要插入的数据:

# 导入MySQL驱动:
import mysql.connector
# 注意把password设为你的root口令,需要提前创建好lhrdb数据库
conn = mysql.connector.connect(user='root', password='lhr', database='lhrdb',host='127.0.0.1',port=3306)
cursor = conn.cursor()
# 创建user表:
cursor.execute('drop table if exists sites')
cursor.execute('create table sites (name varchar(20) primary key, url varchar(200))')
 
# 插入多行记录,注意MySQL的占位符是%s:
sql = "insert into sites (name, url) values (%s, %s)"
val = [
    ('Google', 'https://www.google.com'),
    ('Github', 'https://www.github.com'),
    ('Taobao', 'https://www.taobao.com'),
    ('itpub', 'http://blog.itpub.net/26736162/')
]
 
cursor.executemany(sql, val)
 
# 提交事务:
conn.commit()
print(cursor.rowcount, "条记录插入成功。")
 
cursor.close()
# 运行查询:
cursor = conn.cursor()
cursor.execute('select * from sites')
values = cursor.fetchall()
for x in values:
  print(x)
# 关闭Cursor和Connection:
cursor.close()
conn.close()
运行结果:
4 条记录插入成功。
('Github', 'https://www.github.com')
('Google', 'https://www.google.com')
('itpub', 'http://blog.itpub.net/26736162/')
('Taobao', 'https://www.taobao.com')







About Me

........................................................................................................................

● 本文作者:小麦苗,部分内容整理自网络,若有侵权请联系小麦苗删除

● 本文在itpub( http://blog.itpub.net/26736162 )、博客园( http://www.cnblogs.com/lhrbest )和个人weixin公众号( xiaomaimiaolhr )上有同步更新

● 本文itpub地址: http://blog.itpub.net/26736162

● 本文博客园地址: http://www.cnblogs.com/lhrbest

● 本文pdf版、个人简介及小麦苗云盘地址: http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答: http://blog.itpub.net/26736162/viewspace-2134706/

● DBA宝典今日头条号地址: http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

........................................................................................................................

● QQ群号: 230161599 (满) 、618766405

● weixin群:可加我weixin,我拉大家进群,非诚勿扰

● 联系我请加QQ好友 646634621 ,注明添加缘由

● 于 2019-01-01 06:00 ~ 2019-01-31 24:00 在魔都完成

● 最新修改时间:2019-01-01 06:00 ~ 2019-01-31 24:00

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

........................................................................................................................

小麦苗的微店 https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麦苗出版的数据库类丛书 http://blog.itpub.net/26736162/viewspace-2142121/

小麦苗OCP、OCM、高可用网络班 http://blog.itpub.net/26736162/viewspace-2148098/

小麦苗腾讯课堂主页 https://lhr.ke.qq.com/

........................................................................................................................

使用 weixin客户端 扫描下面的二维码来关注小麦苗的weixin公众号( xiaomaimiaolhr )及QQ群(DBA宝典)、添加小麦苗weixin, 学习最实用的数据库技术。

........................................................................................................................

欢迎与我联系

 

 



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2557188/,如需转载,请注明出处,否则将追究法律责任。

2013-09-01 17:19:54 wujingtianze 阅读数 558
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    12050 人正在学习 去看看 尹成

 面向集合存储,易于存储对象类型的数据

 模式自由

 支持动态查询

 支持完全索引,包含内部对象

 支持查询

 支持复制和故障恢复

 使用高效的二进制数据存储,包括大型对象(如视频等)

 自动处理碎片,以支持云计算层次的扩展性

 支持Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及C++语言的驱动程序,社区

中也提供了对Erlang 及.NET 等平台的驱动程序

 文件存储格式为BSON(一种JSON 的扩展)

 可通过网络访问
2014-06-05 20:48:08 lxf310 阅读数 2578
  • Python-数据

    Python数据库编程视频教程,数据库是MySQL,讲解Python链接MySQL数据库,并对数据库进行增删改查操作。

    12050 人正在学习 去看看 尹成

转载自:http://blog.csdn.net/qiangweiloveforever/article/details/9476003     

本节主要介绍缓冲相关的传输类,缓存的作用就是为了提高读写的效率。Thrift在实现缓存传输的时候首先建立一个缓存的基类,然后需要实现缓存功能的类都可以直接从这个基类继承。下面就详细分析这个基类以及一个具体的实现类。

  缓存基类TBufferBase
  缓存基类就是让传输类所有的读写函数都提供缓存来提高性能。它在通常情况下采用memcpy来设计和实现快路径的读写访问操作,这些操作函数通常都是小、非虚拟和内联函数。TBufferBase是一个抽象的基类,子类必须实现慢路径的读写函数等操作,慢路径的读写等操作主要是为了在缓存已经满或空的情况下执行。首先看看缓存基类的定义,代码如下:
class TBufferBase : public TVirtualTransport<TBufferBase> {  
  1.  public:  
  2.   uint32_t read(uint8_t* buf, uint32_t len) {//读函数  
  3.     uint8_t* new_rBase = rBase_ + len;//得到需要读到的缓存边界  
  4.     if (TDB_LIKELY(new_rBase <= rBound_)) {//判断缓存是否有足够的数据可读,采用了分支预测技术  
  5.       std::memcpy(buf, rBase_, len);//直接内存拷贝  
  6.       rBase_ = new_rBase;//更新新的缓存读基地址  
  7.       return len;//返回读取的长度  
  8.     }  
  9.     return readSlow(buf, len);//如果缓存已经不能够满足读取长度需要就执行慢读  
  10.   }  
  11.   uint32_t readAll(uint8_t* buf, uint32_t len) {  
  12.     uint8_t* new_rBase = rBase_ + len;//同read函数  
  13.     if (TDB_LIKELY(new_rBase <= rBound_)) {  
  14.       std::memcpy(buf, rBase_, len);  
  15.       rBase_ = new_rBase;  
  16.       return len;  
  17.     }  
  18.     return apache::thrift::transport::readAll(*this, buf, len);//调用父类的  
  19.   }  
  20.   void write(const uint8_t* buf, uint32_t len) {//快速写函数  
  21.     uint8_t* new_wBase = wBase_ + len;//写入后的新缓存基地址  
  22.     if (TDB_LIKELY(new_wBase <= wBound_)) {//判断缓存是否有足够的空间可以写入  
  23.       std::memcpy(wBase_, buf, len);//内存拷贝  
  24.       wBase_ = new_wBase;//更新基地址  
  25.       return;  
  26.     }  
  27.     writeSlow(buf, len);//缓存空间不足就调用慢写函数  
  28.   }  
  29.   const uint8_t* borrow(uint8_t* buf, uint32_t* len) {//快速路径借  
  30.     if (TDB_LIKELY(static_cast<ptrdiff_t>(*len) <= rBound_ - rBase_)) {//判断是否足够借的长度  
  31.       *len = static_cast<uint32_t>(rBound_ - rBase_);  
  32.       return rBase_;//返回借的基地址  
  33.     }  
  34.     return borrowSlow(buf, len);//不足就采用慢路径借  
  35.   }  
  36.   void consume(uint32_t len) {//消费函数  
  37.     if (TDB_LIKELY(static_cast<ptrdiff_t>(len) <= rBound_ - rBase_)) {//判断缓存是否够消费  
  38.       rBase_ += len;//更新已经消耗的长度  
  39.     } else {  
  40.       throw TTransportException(TTransportException::BAD_ARGS,  
  41.                                 "consume did not follow a borrow.");//不足抛异常  
  42.     }  
  43.   }  
  44.  protected:  
  45.   virtual uint32_t readSlow(uint8_t* buf, uint32_t len) = 0;//慢函数  
  46.   virtual void writeSlow(const uint8_t* buf, uint32_t len) = 0;  
  47.   virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) = 0;  
  48.   TBufferBase()  
  49.     : rBase_(NULL)  
  50.     , rBound_(NULL)  
  51.     , wBase_(NULL)  
  52.     , wBound_(NULL)  
  53.   {}//构造函数,把所有的缓存空间设置为NULL  
  54.   void setReadBuffer(uint8_t* buf, uint32_t len) {//设置读缓存空间地址  
  55.     rBase_ = buf;//读缓存开始地址  
  56.     rBound_ = buf+len;//读缓存地址界限  
  57.   }  
  58.   void setWriteBuffer(uint8_t* buf, uint32_t len) {//设置写缓存地址空间  
  59.     wBase_ = buf;//起  
  60.     wBound_ = buf+len;//边界  
  61.   }  
  62.   virtual ~TBufferBase() {}  
  63.   uint8_t* rBase_;//读从这儿开始  
  64.   uint8_t* rBound_;//读界限  
  65.   uint8_t* wBase_;//写开始地址  
  66.   uint8_t* wBound_;//写界限  
  67. };  
  从TBufferBase定义可以看出,它也是从虚拟类继承,主要采用了memcpy函数来实现缓存的快速读取,在判断是否有足够的缓存空间可以操作时采用了分支预测技术来提供代码的执行效率,且所有快路径函数都是非虚拟的、内联的小代码量函数。下面继续看看一个具体实现缓存基类的一个子类的情况!
  TBufferedTransport
  缓存传输类是从缓存基类继承而来,它对于读:实际读数据的大小比实际请求的大很多,多余的数据将为将来超过本地缓存的数据服务;对于写:数据在它被发送出去以前将被先写入内存缓存。
  缓存的大小默认是512字节(代码:static const int DEFAULT_BUFFER_SIZE = 512;),提供多个构造函数,可以只指定一个传输类(另一层次的)、也可以指定读写缓存公用的大小或者分别指定。因为它是一个可以实际使用的缓存类,所以需要实现慢读和慢写功能的函数。它还实现了打开函数open、关闭函数close、刷新函数flush等,判断是否有数据处于未决状态函数peek定义和实现如下:
 bool peek() {  
  1.     if (rBase_ == rBound_) {//判断读的基地址与读边界是否重合了,也就是已经读取完毕  
  2.       setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));//是:重新读取底层来的数据  
  3.     }  
  4.     return (rBound_ > rBase_);//边界大于基地址就是有未决状态数据  
  5.   }  
  6. 下面继续看看慢读函数和慢写函数的实现细节(快读和快写继承基类的:也就是默认的读写都是直接从缓存中读取,所谓的快读和快写)。慢读函数实现如下(详细注释):  
  7. uint32_t TBufferedTransport::readSlow(uint8_t* buf, uint32_t len) {  
  8.   uint32_t have = rBound_ - rBase_;//计算还有多少数据在缓存中  
  9.   
  10.   // 如果读取缓存中已经存在的数据不能满足我们,  
  11.   // 我们(也仅仅在这种情况下)应该才从慢路径读数据。  
  12.   assert(have < len);  
  13.   
  14.   // 如果我们有一些数据在缓存,拷贝出来并返回它  
  15.   // 我们不得不返回它而去尝试读更多的数据,因为我们不能保证  
  16.   // 下层传输实际有更多的数据, 因此尝试阻塞式读取它。  
  17.   if (have > 0) {  
  18.     memcpy(buf, rBase_, have);//拷贝数据  
  19.     setReadBuffer(rBuf_.get(), 0);//设置读缓存,基类实现该函数  
  20.     return have;//返回缓存中已经存在的不完整数据  
  21.   }  
  22.   
  23.   // 在我们的缓存中没有更多的数据可用。从下层传输得到更多以达到buffer的大小。  
  24.   // 注意如果len小于rBufSize_可能会产生多种场景否则几乎是没有意义的。  
  25.   setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));//读取数据并设置读缓存  
  26.   
  27.   // 处理我们已有的数据  
  28.   uint32_t give = std::min(len, static_cast<uint32_t>(rBound_ - rBase_));  
  29.   memcpy(buf, rBase_, give);  
  30.   rBase_ += give;  
  31.   
  32.   return give;  
  33. }  
  慢读函数主要考虑的问题就是缓存中还有一部分数据,但是不够我们需要读取的长度;还有比较麻烦的情况是虽然现在缓存中没有数据,但是我们从下层传输去读,读取的长度可能大于、小于或等于我们需要读取的长度,所以需要考虑各种情况。下面继续分析慢写函数实现细节:
void TBufferedTransport::writeSlow(const uint8_t* buf, uint32_t len) {  
  1.   uint32_t have_bytes = wBase_ - wBuf_.get();//计算写缓存区中已有的字节数  
  2.   uint32_t space = wBound_ - wBase_;//计算剩余写缓存空间  
  3.   // 如果在缓存区的空闲空间不能容纳我们的数据,我们采用慢路径写(仅仅)  
  4.   assert(wBound_ - wBase_ < static_cast<ptrdiff_t>(len));  
  5.   
  6.   //已有数据加上需要写入的数据是否大于2倍写缓存区或者缓存区为空  
  7.   if ((have_bytes + len >= 2*wBufSize_) || (have_bytes == 0)) {  
  8.     if (have_bytes > 0) {//缓存大于0且加上需要再写入数据的长度大于2倍缓存区  
  9.       transport_->write(wBuf_.get(), have_bytes);//先将已有数据写入下层传输  
  10.     }  
  11.     transport_->write(buf, len);//写入这次的len长度的数据  
  12.     wBase_ = wBuf_.get();//重新得到写缓存的基地址  
  13.     return;  
  14.   }  
  15.   
  16.   memcpy(wBase_, buf, space);//填充我们的内部缓存区为了写  
  17.   buf += space;  
  18.   len -= space;  
  19.   transport_->write(wBuf_.get(), wBufSize_);//写入下层传输  
  20.   
  21.   assert(len < wBufSize_);  
  22.   memcpy(wBuf_.get(), buf, len);//拷贝剩余的数据到我们的缓存  
  23.   wBase_ = wBuf_.get() + len;//重新得到写缓存基地址  
  24.   return;  
  25. }  
  慢写函数也有棘手的问题,就是我们应该拷贝我们的数据到我们的内部缓存并且从那儿发送出去,或者我们应该仅仅用一次系统调用把当前内部写缓存区的内容写出去,然后再用一次系统调用把我们当前需要写入长度为len的数据再次写入出去。如果当前缓存区的数据加上我们这次需要写入数据的长度至少是我们缓存区长度的两倍,我们将不得不至少调用两次系统调用(缓存区为空时有可能例外),那么我们就不拷贝了。否则我们就是按顺序递加的。具体实现分情况处理,最后我们在看看慢借函数的实现,借相关函数主要是为了实现可变长度编码。慢借函数实现细节如下:
const uint8_t* TBufferedTransport::borrowSlow(uint8_t* buf, uint32_t* len) {  
  1.   (void) buf;  
  2.   (void) len;  
  3.   return NULL;//默认返回空  
  4. }  
         在这个类我们可以看出,它什么也没有做,只是简单的返回NULL,所以需要阻塞去借。按照官方的说法,下面两种行为应该当前的版本中实现,在将来的版本可能会发生改变:
  如果需要借的长度最多为缓存区的长度,那么永远不会返回NULL。依赖底层传输,它应该抛出一个异常或者永远不会挂掉;
  一些借用请求可能内部字节拷贝,如果借用的长度最多是缓存区的一半,那么不去内部拷贝。为了优化性能保存这个限制。
没有更多推荐了,返回首页