python利用跳板机ssh远程连接redis的方法

公司服务器的mysql和redis连接都需要有跳板机,网上有很多python ssh远程连接mysql的,那天我研究了下,利用sshtunnel模块连接上了redis,具体如下:

from sshtunnel import SSHTunnelForwarder  # ssh连接库
import redis # redis模块
server = SSHTunnelForwarder(
                ssh_address_or_host=  , # ssh地址ssh_username=         , # ssh连接的用户名                                       
                ssh_password=   ,  # ssh连接的用户名
remote_bind_address=('远程机器地址', 端口号))

server.start()
r=redis.Redis(host='redis地址', port=server.local_bind_port, decode_responses=True)
如上就可以连接上redis啦,要关闭连接,我用的server.close()

用Python做一只真·多足机器人,钢铁蜈蚣能弯曲还能蠕动

大数据文摘出品

来源:declanoller

编译:徐玲、李世林、陈若朦

足式机器人是如今机器人设计的热点,相较于轮式和履带式机器人,足式设计的优势在于其极强的地形通过能力。

你一定见过模仿人类的两足机器人、犬型和马型的四足机器人、近来爆红的蜘蛛型六足机器人,那你有想过再多来几条腿吗?

控制行走一直是足式机器人的一大设计难点,腿越多则移动越困难。然而,一位名叫Adimin的外国小哥用python做了一只可爬行可弯曲的蜈蚣型机器人。

问:为什么要做设计成蜈蚣型呢?

小哥答:蜈蚣在体型上具有相当的长度,而通过向上弯曲身体还可以具有一定的高度。但是重点是——从来没人做过!蜈蚣机器人够酷、够怪、够有趣!

让“蜈蚣”蠕动起来:双伺服旋转的腿

为实现“蜈蚣”的移动,同时考虑到电力需求,Adimin设计了腿在水平和垂直方向上的旋转功能,分别命名为hip servo 和ankle servo。

于是,腿就能在两个方向上蠕动起来!

此处的所有伺服均由PCA9685 PWM分支板控制——这是一个I2C器件,允许同时控制多达16个伺服器,既便宜又实用。

考虑腿的数量和“蜈蚣”身体的的连接方式,Adimin小哥将主体平台部分设计得较大,给腿的添加留出更多空间;同时在前后两端采取铰链设计(采用金属齿轮MG 996R),不仅能实现身体长度的延伸,还能完成向上弯曲的动作。

“蜈蚣”弯曲起来!

用Python制作多足机器人

“蜈蚣”运动的控制代码是一个分层的类结构。

最基本的单元是Servo部分,使用这部分功能可以直接控制伺服器。

代码中更高级的部分是Leg,其中包含了两个Servo对象,分别用来控制之前提到的 “hip” 和 “ankle” 伺服系统,根据其自身leg_index(2*leg_index和2*leg_index + 1)为它们分配正确的板索引值。

LegPair部分与之Leg类似类似,其中创建了两个Leg对象分别控制左右。

1. b = DriverBoard(args.addr, 16)2.3. ifargs.N_pairs > 4:4. b_front = DriverBoard(40, 8)5.6. pairs = []7. for i in range(args.N_pairs):8. if i < 4:9. lp = LegPair(b, i)10. else:11. lp = LegPair(b_front, i-4)12.13. pairs.append(lp)14.15. start = time()16. while True:17. forp in pairs:18. p.increment_ankles()

让我们来看看这段代码的功能——“蜈蚣”弹跳起来了!

其实,让“蜈蚣”实现行走的部分是increment _ankles()函数。为了解释这一点,让我们回到Servo class。

伺服系统的主要工作是循环移动。为了控制伺服装置的位置,需要向它发送一个特定占空比的脉宽调制(PWM)信号。接下来,我们要找到对应于该点的脉宽调制,即中点脉宽调制(mid_pwm),使它围绕一个点振荡。然后,定义一个脉宽调制幅度(pwm_amplitude),该幅度会决定它在这个循环中相对于中点上下移动的距离。于是,让“蜈蚣”循环移动起来只需通过以下代码:

pwm = int(self.pwm_mid + pwm_amplitude*sin(self.phase + self.phase_offset))

如果要让一条腿以我们预期的“行走”方式运动,hip和ankle伺服系统不可能做完全相同的运动。让我们将运动参数化成x和y,加上时间变量t,构成一个正弦函数,令x(t)=y(t)=sin(ωt),便可以得到下面这个运动曲线:

为了实现行走,则还需要您给其中一个变量提供相位偏移(如上面的代码所示),最终得到一个圆。

在伺服系统的相位偏移变量设计中,Adimin表示分层设置实在是太炫酷了——它能使多条腿连贯运动!

每个腿的伺服对象之间需要一定的相位偏移,而每条腿相对于其他腿也存在相位偏移。因此,我们需要给每个LegPair对象一个高级的相位偏移量,然后每个部分将相应的偏移量分配给它的低级对象。

除了上下跳动以外,Python还能实现“蜈蚣”的其他运动方式:

1. b = DriverBoard(args.addr, 16)2.3. ifargs.N_pairs > 4:4. b_front = DriverBoard(40, 8)5.6. sleep(0.5)7. pairs = []8. for i in range(args.N_pairs):9. if i < 4:10. lp = LegPair(b, i)11. else:12. lp = LegPair(b_front, i-4)13.14. if i%2 == 1:15. lp.set_phase_offset(pi)16. pairs.append(lp)17.18. start = time()19. time_limit = args.runtime20.21. while True:22. forp in pairs:23. p.increment()

自然生物学为机器人设计提供了黄金标准,我们需仍要很长时间才能制造出完成一切动物行为动作的多足机器人。而另一方面,机器人不受生物学的限制,这意味着它们总有可能学习动物天生就不会的新行为。

Python连接MySQL数据库

Python标准数据库接口为Python DB-API, Python DB-API为开发人员提供了数据库应用 编程接口。

Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库:

  • GadFly
  • mSQL
  • MySQL
  • PostgreSQL
  • Microsoft SQL Server 2000 Informix
  • Interbase Oracle Sybase

你可以访问Python数据库接口及API查看详细的支持数据库列表。

不同的数据库你需要下载不同的DB API模块,例如你需要访问Oracle数据库和Mysql数据,你需要下载Oracle和MySQL数据库模块。

DB-API是一个规范。它定义了一系列必须的对象和数据库存取方式, 以便为各种各样的底层数据库系统和多种多样的数据库接口程序提供一致的访问接口。

Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同 的方式操作各数据库。

Python DB-API使用流程:

  1. 引入API模块。
  2. 获取与数据库的连接。
  3. 执行SQL语句和存储过程。
  4. 关闭数据库连接。

1. MySQLdb

MySQLdb是用于Python链接Mysql数据库的接口,它实现了Python 数据库API规范V2.0,基于MySQL C API上建立的。

安装

直接使用pip进行安装,在此之前需要安装一些系统依赖包。

  • CentOS 

yum install gcc python-devel mysql-devel zlib-devel openssl-devel

  • Ubuntu 

sudo apt-get install libmysqlclient-dev libmysqld-dev python-dev python-setuptools

安装完依赖,直接使用pip安装,MySQLdb模块的名字在pip上叫MySQL-python。

pip install MySQL-python

常用函数

Python DB API 2.0 对事务提供了两个方法:

  • commit() 提交
  • rollback() 回滚

cursor用来执行命令的方法:

  • callproc(self, procname, args) 用来执行存储过程,接收的参数为存储过程名和参数列表,返回值为受影响的行数
  • execute(self, query, args) 执行单条sql语句,接收的参数为sql语句本身和使用的参数列表,返回值为受影响的行数
  • executemany(self, query, args) 执行单挑sql语句,但是重复执行参数列表里的参数,返回值为受影响的行数
  • nextset(self) 移动到下一个结果集

cursor用来接收返回值的方法:

  • fetchall(self) 接收全部的返回结果行.
  • fetchmany(self, size=None) 接收size条返回结果行.如果size的值大于返回的结果行的数量,则会返回cursor.arraysize条数据.
  • fetchone(self) 返回一条结果行.
  • rowcount 这是一个只读属性,并返回执行execute() 方法后影响的行数。
  • scroll(self, value, mode=’relative’) 移动指针到某一行; 如果mode=’relative’,则表示从当前所在行移动value条,如果 mode=’absolute’,则表示从结果集的第一行移动value条.

实例

#!/usr/bin/env python# -*- coding: utf-8 -*-import MySQLdb as mdb

# 连接数据库

conn = mdb.connect(‘localhost’, ‘root’, ‘root’)

# 也可以使用关键字参数

conn = mdb.connect(host=’127.0.0.1′, port=3306, user=’root’, passwd=’root’, db=’test’, charset=’utf8′)

# 也可以使用字典进行连接参数的管理

config = {

    ‘host’: ‘127.0.0.1’,

    ‘port’: 3306,

    ‘user’: ‘root’,

    ‘passwd’: ‘root’,

    ‘db’: ‘test’,

    ‘charset’: ‘utf8’

}

conn = mdb.connect(**config)

# 如果使用事务引擎,可以设置自动提交事务,或者在每次操作完成后手动提交事务conn.commit()

conn.autocommit(1)    # conn.autocommit(True)

# 使用cursor()方法获取操作游标

cursor = conn.cursor()# 因该模块底层其实是调用CAPI的,所以,需要先得到当前指向数据库的指针。

try:

    # 创建数据库

    DB_NAME = ‘test’

    cursor.execute(‘DROP DATABASE IF EXISTS %s’ %DB_NAME)

    cursor.execute(‘CREATE DATABASE IF NOT EXISTS %s’ %DB_NAME)

    conn.select_db(DB_NAME)

    #创建表

    TABLE_NAME = ‘user’

    cursor.execute(‘CREATE TABLE %s(id int primary key,name varchar(30))’ %TABLE_NAME)

    # 插入单条数据

    sql = ‘INSERT INTO user values(“%d”,”%s”)’ %(1,”jack”)

    # 不建议直接拼接sql,占位符方面可能会出问题,execute提供了直接传值

    value = [2,’John’]

    cursor.execute(‘INSERT INTO test values(%s,%s)’,value)

    # 批量插入数据

    values = []

    for i in range(3, 20):

        values.append((i,’kk’+str(i)))

    cursor.executemany(‘INSERT INTO user values(%s,%s)’,values)

    # 查询数据条目

    count = cursor.execute(‘SELECT * FROM %s’ %TABLE_NAME)

    print ‘total records: %d’ %count

    print ‘total records:’, cursor.rowcount

    # 获取表名信息

    desc = cursor.description

    print “%s %3s” % (desc[0][0], desc[1][0])

    # 查询一条记录

    print ‘fetch one record:’

    result = cursor.fetchone()

    print result

    print ‘id: %s,name: %s’ %(result[0],result[1])

    # 查询多条记录

    print ‘fetch five record:’

    results = cursor.fetchmany(5)

    for r in results:

        print r

    # 查询所有记录

    # 重置游标位置,偏移量:大于0向后移动;小于0向前移动,mode默认是relative

    # relative:表示从当前所在的行开始移动; absolute:表示从第一行开始移动

    cursor.scroll(0,mode=’absolute’)

    results = cursor.fetchall()

    for r in results:

        print r

    cursor.scroll(-2)

    results = cursor.fetchall()

    for r in results:

        print r

    # 更新记录

    cursor.execute(‘UPDATE %s SET name = “%s” WHERE id = %s’ %(TABLE_NAME,’Jack’,1))

    # 删除记录

    cursor.execute(‘DELETE FROM %s WHERE id = %s’ %(TABLE_NAME,2))

    # 如果没有设置自动提交事务,则这里需要手动提交一次

    conn.commit()except:

    import traceback

    traceback.print_exc()

    # 发生错误时会滚

    conn.rollback()finally:

    # 关闭游标连接

    cursor.close()

    # 关闭数据库连接

    conn.close()

查询时返回字典结构

MySQLdb默认查询结果都是返回tuple,通过使用不同的游标可以改变输出格式,这里传递一个cursors.DictCursor参数。

import MySQLdb.cursors

conn = MySQLdb.connect(host=’localhost’, user=’root’, passwd=’root’, db=’test’, cursorclass=MySQLdb.cursors.DictCursor)

cursor = conn.cursor()

cursor.execute(‘select * from user’)

r = cursor.fetchall()print r# 当使用位置参数或字典管理参数时,必须导入MySQLdb.cursors模块

# 也可以用下面的写法import MySQLdb as mdb

conn  = mdb.connect(‘localhost’, ‘root’, ‘root’, ‘test’)

cursor = conn.cursor(cursorclass=mdb.cursors.DictCursor)

cursor.execute(‘select * from user’)

r = cursor.fetchall()print r

MySQLdb取回大结果集的技巧

普通的操作无论是fetchall()还是fetchone()都是先将数据载入到本地再进行计算,大量的数据会导致内存资源消耗光。解决办法是使用SSCurosr光标来处理。

然而,在python3下,MySQLdb模块不再提供支持,此时可以使用另一个模块PyMySQL,它支持python2和python3。

2. PyMySQL

PyMySQL是一个纯Python写的MySQL客户端,它的目标是替代MySQLdb,可以在CPython、PyPy、IronPython和Jython环境下运行。PyMySQL在MIT许可下发布。

PyMySQL的性能和MySQLdb几乎相当,如果对性能要求
不是特别的强,使用PyMySQL将更加方便。

PyMySQL的使用方法和MySQLdb几乎一样。

安装

pip install pymysql

实例

#!/usr/bin/env python# -*- coding: utf-8 -*-import pymysql

config = {

    ‘host’: ‘127.0.0.1’,

    ‘port’: 3306,

    ‘user’: ‘root’,

    ‘passwd’: ‘root’,

    ‘charset’:’utf8mb4′,

    ‘cursorclass’:pymysql.cursors.DictCursor

    }

conn = pymysql.connect(**config)

conn.autocommit(1)

cursor = conn.cursor()

try:

    # 创建数据库

    DB_NAME = ‘test’

    cursor.execute(‘DROP DATABASE IF EXISTS %s’ %DB_NAME)

    cursor.execute(‘CREATE DATABASE IF NOT EXISTS %s’ %DB_NAME)

    conn.select_db(DB_NAME)

    #创建表

    TABLE_NAME = ‘user’

    cursor.execute(‘CREATE TABLE %s(id int primary key,name varchar(30))’ %TABLE_NAME)

    # 批量插入纪录

    values = []

    for i in range(20):

        values.append((i,’kk’+str(i)))

    cursor.executemany(‘INSERT INTO user values(%s,%s)’,values)

    # 查询数据条目

    count = cursor.execute(‘SELECT * FROM %s’ %TABLE_NAME)

    print ‘total records:’, cursor.rowcount

    # 获取表名信息

    desc = cursor.description

    print “%s %3s” % (desc[0][0], desc[1][0])

    cursor.scroll(10,mode=’absolute’)

    results = cursor.fetchall()

    for result in results:

        print result

except:

    import traceback

    traceback.print_exc()

    # 发生错误时会滚

    conn.rollback()finally:

    # 关闭游标连接

    cursor.close()

    # 关闭数据库连接

    conn.close()

输出结果:

total records: 20

id name

{u’id’: 10, u’name’: u’kk10′}

{u’id’: 11, u’name’: u’kk11′}

{u’id’: 12, u’name’: u’kk12′}

{u’id’: 13, u’name’: u’kk13′}

{u’id’: 14, u’name’: u’kk14′}

{u’id’: 15, u’name’: u’kk15′}

{u’id’: 16, u’name’: u’kk16′}

{u’id’: 17, u’name’: u’kk17′}

{u’id’: 18, u’name’: u’kk18′}

{u’id’: 19, u’name’: u’kk19′}