#!/usr/bin/env python #在环境变量env中找Python
#coding: utf8
1.自动补全
配置环境: 创建以下文件
vim /usr/local/bin/tab.py
输入:
import readline
import rlcompleter
readline.parse_and_bind('tab:complete')
存储后设置 SPYTHONSTARTUP
vim ~/.bash_profile 增加以下内容
再最后的export PATH前加
PYTHONSTARTUP=/usr/local/bin/tab.py
export PATH PYTHONSTARTUP
保存后修改可执行权限
chmod +x /usr/local/bin/tab.py
source ~/.bash_profile(马上生效)
验证
echo SPYTHONSTARTUP(有值即可)
补全
#source /python_note/tab.sh 即可
关键字查询: improt keyword
keyword.kwlist
循环获取 I %s %(ine for line in data)
思路: 根据功能分函数,函数先写框架
cmp 比较大小
list('abcd') >>>['a','b','c','d']
int 可转进制 int('10',base=2) base指定进制数
abs 返回绝对值
divmod(10,3) >>>(3,1) 可得商和余
pow 指数运算,即几次方
round 四舍五入 round(5.0/3,2)
hex 16进制数
oct 8进制
bin 2进制
ord ACCII码
chr 转为ACCII编码
range(5) 生成0~5的列表
from random improt randint
randint(1,100) 随机生成一个(1,100)内的数
enumerate 返回元组(下标,元素) 用list(enumerate(1,2))
reversed (反转序列) 也可 [::-1]
sorted 排序
string.letters (字母大小写列表)
string.digits (数字列表)
%15s%5s%('name','ager') 格式对齐
%-15s%-5s%('name','ager')左对齐
%s%s%(-10,'name',-5,'ager') *占位 -10和-5
string.centen(48) 居中字符串
string.capitalize() 首字母大写
string.ljust(40,#) 左对齐
string.rjust(40,#)右对齐
string.count('l') 统计l出现次数
string.endswith('o') 是否以O结尾
string.startswith('e') 是否e开头
string.islower 是否小写,有任一大写则返回flase
string.isupper 是否大写,有任一小写则返回flase
string.isdigit 是否数字
string.isacpha 是否字母
string.isalnum 是否数字和字母
string.strip 去除字符串两端的空白,可加参数去除指定 string.strip('!') 去除两端!字符串,不去除中间
string.lstrip() 去除左端空白 string.rstrip() 去除右端空白,
** string.rstrip('\r\n') 去除右端\r,\n,\r\n
string.vpper 小写转大写
string.sqlit('.') 以.切割字符串,返回列表
string.replace('o','a') 把o替换为a
improt subprocess 执行系统命令模块
subprocess.call('ls -l /home',shell=True)
string.Template() 字符串模块
data=f.read().decode('gb1803')
f.write(date.encode('utf8'))
列表切片增加:
alist=[10,11,12,13,'zh','li',30]
alist[5:5]=['ww','zl'] (列表中间插入)
alist=[10,11,12,13,'zh','ww','zl','li',30]
列表删除
del alist[-1] 删除最后一项
alist.pop() 删除最后一项并返回删除项
alist.pop(3) 删除下标3的项
alist.remove(12) 根据值删除,相同值时只删第一个
alist.count(10) 统计10出现次数
alist.extend() 拆分元素增加
alist.index('new') 返回元素的下标,多个时只返回第一个,无则报错
alist.insert(0,200) 向下标0插入200
alist.reverse() 反转列表
alist.sort() 排序,默认升序排列
random.shuffle(alist) 打乱排序
alist.sort(reversed=True) 排序时反转
alist.len() 获取长度
alist.max() 获取最大值
alist.min() 最小值
字符串拼接
str_list=['h','e','o']
'.'.join(str_list) #以.号连接
输出'h.e.o'
多用列表,效率高
字典
adict['name'] 字典访问
for key in adict:
print "%s:%s" %(key,adict[key]) 字典循环
"(name)s:%(age)s"% adict 获取值
adict.pop(key) 弹出健
adict.popitem() 随机弹
adict.setdefault('mail','bobcatudo') 有则不变更
adict.keys() 返回健
adict.values() 返回值
adict.items() 返回健和值
adict.update(bdict) 字典相加
多if 判断多个条件时某些值时用字典
cmds = {'0':push_it,'1':pop_it,'2':view_it}
choice=raw_input(prompt).strip()[0] #去掉输入的空格并获取第一个值
cmds[choice]() #用字典匹配获取对应的值得调用函数
元组
tuple()
创建单元组时要在后面加,
a=('10',)
元组不可变,但元组中的列表可以变
atuple=(1,[],2)
atuple[1].append(10)
atuple[1].append(20)
结果是 atuple=(1,[10,20],2)
max() 返回最大
mint() 返回最小
alist=['hello','word']
enumerate(alist) 返回函数对象
list(enumerate(alist))
集合: 集合可以去重 set(['1','2'])
判断: big=x if x>y else y
生成器表达式:不真正创建列,返回一个生成器,使用时才生成
(expr for iter_var in iterable if (ond_expr))
print "\r" # \r不换行,后面加,连接。
%c 数字转化为ACCII
%s 先转化为字符串后
%d 整数类型,只留整数
% d 前面留空格兼容负数
%05d 前面空格补0
%+5d 正数前面显示+号
%f 浮点数
%5.3f 宽度为5,小数为3位
%i int
%e 科学计数法
%o 8进制数
%#o 显示前缀
花括号格式化
" {} is {} yesas old".format('bob','23')
推荐用花括号格式化
" {0[0]} is {0[1]} yesas old".format(alist)
第一列左对齐宽度为8,第二列为宽度5左对齐,有对齐
" {0:8s} is {1:<5d} yesas old".format('bob','23')
字符串模版
ori_txt='HI ${name},I WILL SEE YOU ${day}'
t=string.Template(ori_txt)
t.substitute(name='bob',day='tomorrow')
调用系统命令建议使用 subprocess
subprocess.call('ls /home', shell=True)
字典:{} 花括号,无序。
{}.fromkeys(('tom','bob','alice'),7) #值固定为7时可以批量创建
输出:{'bob':7,'alice':7,'tom':7}
adict['key'] 访问字典
adict.pop['key'] 删除字典
del adict['key'] 删除字典
adict.popitem() 随机删除值并返回删除的值
adict.clear 清除字典
adict ={'age':7,'name':'bob'}
'%(name)s:%(age)s' % adict
a=adict.copy() 深复制,值互不影响
clist=alist[:] 列表复制,值互不影响
adict.get('key') 取出值,不存在返回none
adict.get('key',23) 取出值,不存在返回23
adict.get('key','nout found') 取出值,不存在返回not found
adict.setdefault('age',20) 设置值,存在则不改变.
adict.keys() 获取key的列表
adict.items() 获取值和key的列表
adict.values()获取值的列表
bdict={'age':23,'name':'bob','emil':'[email protected]'}
{value:key for key,value in bdict.items()} #key和value对换,注意value有相同值时会丢项目
adict.update(bdict) 更新字典,可以把bdict合并到adict里
隐藏密码输入
import getpass
getpass.getpass("password")
集合
aset= set ('abc')
bset= set ('cde')
aset & base 等于 set([c]) 交集
aset | base 等于 set([a b c d e]) 交集
aset - bset 等于 set ([a b]) 差补,即a里有,b里没有,可以做2个文件的比较差异。
set.add() 添加成员
set.remove() 移除成员
set.update() 批量添加成员
批量执行命令,判断每一个语句结果
commands = [
'mkdir /tmp/adb',
'echo hello > /tmp/abc/myfile.txt',
'cat /tmp/abc/myfile.txt'
]
def fun0():
def fun1():
def fun2():
func_dict = {0:func0,1:func1,2:func2}
for i in range(len(commands)):
ret_val=subprocess.call(commands[i],shell=True)
if ret_val !=0:
fun_dict[i]()
break
迭代器
myiter= iter('abc')
myiter.next()
到最后会报错
for 循环可以便利所有类型。
生成器表达式,使用时才生成,节省内存
('172.168.1.%s' %s i for i in range(1,255))
文件处理
.readline() #以/n 结束为一行
flush() 立即同步到文件
\r #回车不换行,即在同一行中
os
os.sep # /
os.curdir #.
os.pardir #..
os.linesep #\n
os.mknod('test.txt') #创建空文件
os.symlink('/etc/host','zhuji') #快捷方式
os.chmod('test.txt',0644) #0代表8进制,需写。
cPickle(c语言写的,数度快),Pickle模块 存储对象类型,方便取出。
adict={'name':'bob'}
f=open('/tmp.tx','w')
cPickle.dump(adict,f) #保存字典到文本
cPickle.load(f) #读取文件中的数据
错误:
keyboardinterrupt :用户中断执行
EOFError :没有内健输入,到达EOF标记 ,
IOError :输入输出操作失败
分析可能产生异常的位置再加try
一个try 可以有多个
except 如:
except (keyboardinterrupt,eoferror) #多个错误类型用()包含
except(valueError)
except valueerror ,e : # e保存错误信息
BaseException 所有异常
keyboardinterrupt #用户中断 即ctrl+c 取消
eoferror 没有内健输入 即ctrl+d
IOError 输入/输出操作失败 ,打开不存在的文件
try:
except:
else: #没报错才执行
finally: #都执行
with 可以简化代码
如:
with open('/etc/fstab') as fs:
print fs.readline()
不必用fs.clock 关闭邮件
定义异常
if not 0
raise ValueError , "age out of rang" #必须为已知异常
断言异常
assert 0
fun()
b=fun #等于b引用fun的空间
def fun (age,name='bob') #默认参数=需放后面
print '%s:%s' (name,age)
函数参数组
def get_args(*arge)
print args
get_args(10,20,30)
def get_kwargs(**kwargs): #字典接受数据
print jiejiw
get_kwargs(name='jj',age=23)
info=['bob',23]
get_info(*info) #代表传入列表的2个参数
info_dict={'name':'bob','aee':34}
get_info(**info_dict) #拆开字典,传入值
choice('+-') 随机选择一项
匿名函数
a= lambda x,y:x+y #定义匿名函数
a(20,30)
字典使用匿名函数
mcds={'+': lambda x,y:x+y,'-':lambda x,y:x-y}
num_list=[randint(1,100) for i in range(10)]
filter(函数,序列) ,函数或许序列的作为参数,函数结果为真保留,为假过滤
print filter(lambda x:x%2,num_list)
map(lambda x:x*2,num_list) #获取序列的值
reduce(lambda x,y:x+y,num_list) #统计序列中的和,将第一个序列和第二个相加,结果在和第三个相加
vim 自动缩进
set ai
时间
data=time.strftime("%Y-%m-%d")
检查文件
md5sum
global #定义全局变量
偏函数
def add(x,y):
return x+y
import functools
add10=functools.partial(add,10) #可以固定X值的模式,第一个参数时函数,第二个参数没指定y=10时,按顺序赋值
add10(3) #等于13
递归
例子:排序 ,弹出列表最后一个值和列表每项比较,小的放小列表,大的放大列表,最后放回 小+弹出的值+大,如果列表为空或1时,返回列表
def sou(alist):
if len(alist) == 0 or len(alist) == 1:
return alist
num = alist.pop()
l = []
m = []
for i in alist:
if i < num:
l.append(i)
else:
m.append(i)
return sou(l) + [num] + sou(m)
if name == 'main':
alist = [random.randint(1, 100) for i in range(10)]
print alist
print sou(alist)
闭包
若内部变量想在内部的内部可以使用,则需为可变对象
def count(start=0):
count=[start]
def incr():
counter[0]+=1
return counter[0]
return incr #闭包返回的是函数
if name=='main':
a=count()
b=count(10)
print a()
print a()
print b()
装饰器
mport time
def deco(fun):
def timeit():
start=time.time()
ret_val=fun()
end=time.time()
return ret_val,end-start
return timeit #放回函数
@deco #装饰器,将loop当deco的参数运行
def loop():
result=[]
for i in range(1,11):
result.append(i)
time.sleep(0.3)
return result
if name == 'main':
print loop()
hashlib 模块,作文件校验。
m=hashlib.md5('hello world!')
m.hexdigest()
tarfile 直接访问tar文件
tar=tarfile.open('2.tar.gz','w:gz') #创建tar文件
tar.add('day01') #压缩文件
tar.close()
tar=tarfile.open('day01.tar.gz','r:') #自动识别压缩方式
tar.extractall('/tmp/') #指定解压位置
os.walk 获取文件夹下文件列表
for path,foler,files in os.walk('/etc/')
for each_file in files:
os.path.join(path,each_file)
testcase/增量备份.py
class ClassName(object): #object 是基类或父类
count=0
ClassName.count #引用类
mc=ClassName()
mc.count
mc.name='tom'
mc.dist
name:tom 只显示实例的属性
构造器函数
init 调用类时,先执行
class MyClass(object):
def init(self,name): #绑定方法,需先实例化才能调用,self是变量名,可自己设,如下a=..
self.name=name #实例的属性,外部需调用此属性时,要绑定此属性
def display_name(self):
print name #显示bob
if name=='main':
a=MyClass('bob') #实例对象化对象时,会把实例对象传给self, 即a给self,因此只传一个参数即可
print a.name # 显示bob
a.display_name()
b=MyClass('alice')
b.display_name()
绑定方法
class Hotel(object):
def init(self,room,cf=1.0,bf=15):
self.room=room
self.cf=cf
self.bf=bf
def calc_all(self,days=1):
return (self.roomself.cf+self.bf) days
if name == 'main':
stroom=Hotel(200)
print stroom.calc_all()
print stroom.calc_all(2)
bigroom=Hotel(300)
print stroom.calc_all()
print stroom.calc_all(2)
#非绑定方法
print Hotel.calc_all(stroom)
继承类:
addbook.py
class AddrBook(object):
def init(self,name,phone):
self.name=name
self.phone=phone
def get_phone(self):
return self.phone
def updata_phone(self,newphone):
self.phone=newphone
print '%s updata phone %s' %(self.name,self.phone)
if name == 'main':
bob=AddrBook('bob','1333333')
alis=AddrBook('alis','144444')
print bob.get_phone()
bob.updata_phone('155555')
print bob.get_phone()
email.py
import addbook
class EmplAddrBook(addbook.AddrBook): #继承上一个类
def init(self,name,phone,email):
addbook.AddrBook.init(self,name,phone)
super(EmplAddrBook,self).__init__(name,phone) #super 方法继承
self.email=email
def get_email(self):
return self.email
组合:
class UserInfo(object):
def init(self,phone,email):
self.phone=phone
self.email=email
def get_phone(self):
return self.phone
def updata_phone(self,newphone):
self.phone=newphone
return self.phone
def get_email(self):
return self.email
def updata_email(self,newemail):
self.email=newemail
return self.email
class AddrBook(object):
def init(self,name,phone,email):
self.name=name
self.info=UserInfo(phone,email) #引用上一个类定义的属性
多重继承
class A(object):
def get_name(self):
print 'in a'
def start(self):
print '' 20
class B(object):
def display_name(self):
print 'in b'
def start(self):
print '#' * 20
class C(A,B):
pass
if name == 'main':
c=C()
c.display_name() #继承所有父类的方法
c.get_name()
c.start() #先在A中查找,有就打印了
issubclass(B,A) #判断B是否A的子类
isinstance(b,B) #判断b是否B的实例
hasattr() #判断一个对象是否另一个特定的属性
getattr() #获得一个对象的属性
setattr() #设置一个对象的属性
delattr() #删除一个对象的属性
私有化
class A(object):
def init(self):
self.name='bob' #开头的是私有化
def get_name(self):
return self.__name
a =A()
a.get_name()
class Books(object):
def init(self,title,author):
self.title=title
self.author=author
def str(self): #字符串初始化,比下面更易读
return self.title
def repr(self):
return self.title #字符串初始化,
def call(self): #方法调用
print '%s is jiw %s'%(self.title,self.author)
if name == 'main':
py_book=Books('sss','wew')
print py_book
py_book()
正则:
. 匹配任意字符
[..x-y..] 匹配字符组里的任意字符
[^..x-y..] 匹配不再字符组里的任意字符
\d 匹配任意数字【0-9】
\D 非数字字符
\w 匹配任意数字字母下划线 【0-9a-zA-Z】
\W 非数字字母下划线
\s 匹配空白字符【\r\v\f\t\n】
\S 非空白字符
literal 匹配字符串的值
re1|rel2 匹配re1或re2
匹配前面出现的零次或多次
匹配前面出现的一次或多次
? 匹配前面出现的零次或一次
{M,N} 匹配前面出现至少M次,最多N次
^ 匹配字符串的开始
$ 匹配字符串的结尾
\b 匹配字符串的边界 #egrep '\btom\b' ,只匹配 tom
() 对正则表达式分组
\nn 匹配已保存的子组
import re
a=re.match('查找内容','查找目标') #正则查找,但只匹配开始,隐含有^
re.search('查找内容','查找目标') #正则查找,仅匹配一个
a.group() #获取查找内容
c=re.findall('the','apple the,teh the 22') #查找所有,结果放入列表,可以直接输出
print c
c=re.finditer('the','apple the ,teh the 22') #返回一个迭代器对象
for i in c:
print i.group() #打印迭代器内容
IP地址正则表达式
([0-9]{1,3}.){3}[0-9]{1,3}
MAC地址匹配加符号
%/(..)(..)(..)(..)$/\1:\2:\:3\/g
complie 大量匹配时用,可以提高效率
patt=re.compile('foo')
m=patt.match('food')
print m.group()
split 分隔符切割
mylist=re.split('.|-','hello-world.data')
print mylist
import re
z='firefox'
dica={}
data=open('access_log')
for i in data:
m=re.search(z,i)
if m:
ip=m.group()
dica[ip]=dica.get(ip,0)+1
print dica
sub
re.sub() #替换某一个字符
re.sub('X','MR','Hi X ,nice to meet you')
data='my phone number is :1588888696'
m= re.search('.+(\d+)',data)
print m.groups() #获取了()里的值
贪婪匹配 ,即最长匹配,即可能多的匹配
m=re.search('.+?(\d+)',data) #?阻止贪婪匹配
m.groups()
('1588888696')
socket函数与方法:
创建TCP服务器
创建TCP服务器的主要步奏:
1.创建服务器套接字:s=socket.socket()
2.绑定地址到套接字:s.bind()
3.启动监听:s.listen()
4.接受客户连接:s.accept()
5.与客户端通信:recv()/send()
6.关闭套接字:s.close()
import socket
host='' #空串表示所有地址
port=1234
addr=(host,port)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #网络的tcp的套接字
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #套接字选项,允许程序退出后立即可以执行,1是允许
s.bind(addr)
s.listen(1) #为一个程序提供服务
while True: #持续链接
cli_sock,cli_addr = s.accept() #返回一个套接字元组和地址,yum -y install telnet
print "Client connected from:",cli_addr #telnet 127.0.0.1 1234
while True:
cli_sock.send(" i c u \r \n")
data= cli_sock.recv(1024) #每次接受1024字节数据
if data.strip() == '' :
break
print data
cli_sock.close()
s.close()
==================================
爬取图片
import urllib2
html=urllib2.urlopen('http://www.baidu.com/a.jpg')
data=html.read()
html.close
with open('a.jpg','w') as fobj:
fobj.write(data)
分析apache访问日志
编写一个apche日志分析脚本
1.统计每个客户端的访问apache服务器的次数
2.将统计信息通过字典的方式显示出来
3.分别统计客户端时firefox和msie的访问次数
4.分别使用函数式编程和面向对象编程的方式实现
import re
def count_patt(fname,patt):
result={}
cpatt=re.compile(patt)
with open(fname) as fobf:
for line in fobf:
m=cpatt.search(line) #全句查找
if m:
key=m.group()
result[key]=result.get(key,0)+1 #获取字典的值,没有则用0
return result
def quick_sort(str_list):
if len(str_list)==0 or len(str_list) ==1:
return str_list
middle=str_list.pop()
smaller=[]
large=[]
for item in str_list:
if item[-1] < middle[-1]:
smaller.append(item)
else:
large.append(item)
return quick_sort(large) +[middle]+quick_sort(smaller)
if name == 'main':
log_file='access_log-2016077'
ip='^(\d+.){3}\d+'
br='Firefox|MSIE'
print count_patt(log_file,ip)
print count_patt(log_file,br)
a=count_patt(log_file,ip)
print a
print quick_sort(a.items())
多线程:
import threading
import subprocess,threading
def myiping(ip):
a=subprocess.call('ping -c2 -i0.1 %s &>/dev/null' % ip,shell=True)
if a:
print '%s is down'%ip
else:
print '%s is up'%ip
net=['172.40.55.%s' %i for i in range(1,255)]
for i in net:
t=threading.Thread(target=myiping,args=[i]) #target是函数名,args是参数
t.start()
利用多线程实现ssh并发访问
import paramiko
host = '192.168.4.100'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username='root', password='123456')
ssh.exec_command('touch /hh22.txt')
stdin,stdout,stderr=ssh.exec_command('ls /') #将结果赋值给3个变量
print stdout.read() #获取输出结果
4 案例4:利用多线程实现ssh并发访问
4.1 问题
编写ssh客户端脚本,主要要求如下:
在文件中取出所有远程主机IP地址
在shell命令行中接受远程服务器IP地址文件、远程服务器密码以及在远程主机上执行的命令
通过多线程实现在所有的远程服务器上并发执行命令
方案
python的paramiko模块可以实现ssh客户端的功能,使用起来也比较简单。但是当服务器非常多的时候,每台服务器上执行完全相同的简单操作,也会花费大量的时间。
通过ssh加上多线程,可以实现并发访问。为了将程序写的灵活性更强,把要执行的命令以位置参数的方式来提供。
4.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:编写脚本
[root@py01 bin]# vim remote_comm.py
#!/usr/bin/env python
import paramiko
import os
import sys
import threading
def remote_comm(host, password, comm):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username='root', password=password)
stdin, stdout, stderr = ssh.exec_command(comm)
out = stdout.read()
err = stderr.read()
if out:
print "[%s:out]: %s" % (host, out),
if err:
print "%s:Error: %s", (host, err),
ssh.close()
if __name__ == '__main__':
if len(sys.argv) != 4:
print "Usage: %s ipfile password 'comm'" % sys.argv[0]
sys.exit(1)
ipfile = sys.argv[1]
if not os.path.isfile(ipfile):
print "No such file: %s" % ipfile
sys.exit(2)
password = sys.argv[2]
comm = sys.argv[3]
with open(ipfile) as fobj:
for line in fobj:
ip = line.strip()
t = threading.Thread(target=remote_comm, args=(ip, password, comm))
t.start()
xinetd:
yum -y install xinetd
vim /etc/xinetd.d/pyserver
service pyserver
{
flags = NAMEINARGS
type = UNLISTED
socket_type = stream
port = 21345
protocol = tcp
wait = no
user = root
server = /root/lgh/ex1.py
server_args = /root/lgh/ex1.py
}
vim /root/lgh/ex1.py
#!/usr/bin/env python
import sys
sys.stdout.write('sdfe')
sys.stdout.flush() #刷新缓存
父进程
os.fork()
celery 框架
import os
import time
pid=os.fork()
print pid
if pid:
print "in par"
time.sleep(15)
print "par ext"
else:
print "in chi"
for i in range(5):
print time.ctime()
time.sleep(1)
print "ch exit"
父进通过os.wait()来得到子进程是否终止信息
python3.0
依赖
yum -y install gcc gcc-c++ opensll-devel libffi-devel readline-devel
字符串直接是UNICOOK
去除回车
print(line,end='')
输入:
input
5/3 直接返回浮点
5//3 返回整数
异常
except IndexError as e #2用逗号,3用as
raise valueerror,'valll.' #2用逗号
raise valueerror('xxxxx') #3用括号
range() 和2版本的xrange()一样。
adict.keys 返回对象,不是列表。
整数统一了,没长整数
8进制数改成0o11
3也有可变集和和不可变集和
{} 是可变集和
frozenset([])是不可变集和。
数据库
模块 MySQL-python 1.2.5 py2.7
mysqlpy 2.1.7 py3.0
pip3 install PyMySQL 安装组建
插入数据
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="insert into depar(dep_name) values(%s)"
result=cur.execute(sql1,('deve',)) #后面是元组,单元组要加逗号
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
执行后放回1 是影响1行。
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="insert into depar(dep_name) values(%s)"
data=[('hr',),('op',),('财务',)]
result=cur.executemany(sql1,data) #多个数据
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="insert into depar(dep_name) values(%s,%s)"
data=[('hr','aa'),('op','bb'),('财务','cc')]
result=cur.executemany(sql1,data) #多个数据
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
sql1="insert into salary(date,emp_id,basic,extra) values(%s,%s,%s,%s)"
data=(time.strftime('%Y-%m-%d'),1,10000,5000)
result=cur.execute(sql1,data) #多个数据
查询
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="select * from departments"
result=cur.fetchone() #获取一条数据
result2=cur.fetchmany(2) #获取2条数据
cur.scroll(1,mode="ralative") #相对当前位置移动
result3=cur.fetchmany(2) #获取2条数据
result3=cur.fetchall() #获取全部数据
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
移动游标获取数据
cur.scroll(1,mode="ralative") #相对当前位置移动
cur.scroll(2,mode="absolute") #相对查询结果位置移动
更新
sql1="updata salary set dep=%s where dep=%s"
result=cur.execute(sql1,('oppp','op')) #多个数据
删除
sql1="delete from salary where dep=%s"
result=cur.execute(sql1,('oppp',)) #多个数据
SQLalchemy
连接数据库
安装
pip3 install SQLalchemy
连接
数据库类型+驱动://user:password@host/dbname[?key=value...] #[?连接参数]
from sqlalchemy import create_engine
engine=create_engine('mysql+pymysql://root:123456@localhost/dbtest',encoding='utf8',echo=True)
echo=True 表示将日志输出到终端屏幕,默认为False,调试时用
声明映射
当使用ORM的时候,配置过程从描述数据库表开始
通过自定义类映射相应的表
通过声明系统实现类映射
首先通过声明系统,定义基类
from sqlalchemy.ext.declarative import declarative_base
Base=declarative_base() #声明基类
创建映射类
一旦创建了基类,就可以创建自定义映射类了
from sqlalchemy import Column,Integer,String
class Departments(Base):
tablename='departments'
dep_id=Column(Integer,primary_key=True)
dep_name=Column(String(20))
def repr(self):
return ""% self.dep_name
#repr是可选项 输出类的信息,可print(Base)查看
创建架构
类构建完成后,表的信息将被写入到表的元数据(metadata)
print(Departments.tablename) #查看
创建表
if name == 'main':
Base.metadata.create_all(engine)
创建映射类的实例
创建实例时,并不会真正在表中添加记录
dep_dev=Departments(dep_name='developments') #创建会话后才插入数据
print(dep_dev.dep_name)
print(dep_dev.dep_id)
创建会话类
ORM访问数据库的句柄被称做Session
from sqlalchemy.orm import sessionmaker
Session=sessionmaker(bind=engine)
如果在创建session前还未创建engine,操作如下
Session=sessionmaker()
Session.configure(bind=engine) #创建engine后执行
添加新对象
会话类的实例对象用于绑定到数据库
实例化类的对象,并不打开任何连接
当实例初次使用,它将从Engine维护的连接池中获得一个连接
当所有的事务均被commit或会话对象被关闭时,连接结束
session=Session()
session.add(dep_dev)
session.commit()
print(str(dep_dev.dep_id))
session.close()
添加新对象
。可以创建多个实例,批量添加记录
。如果有中文,注意engine的参数
engine=create_engine('mysql+pymysql://root:123456@localhost/dbtest?charset=utf8',encoding='utf8',echo=True)
Base.metadata.create_all(engine)
dep_hr=Departments(dep_name='hr')
dep_op = Departments(dep_name='op')
dep_finance = Departments(dep_name='财务')
dep_xz = Departments(dep_name='行政')
Session=sessionmaker(bind=engine)
session=Session()
session.add_all([dep_hr,dep_op,dep_xz]) #多行用[]
session.commit()
session.close()
ORM映射关系也可用于表间创建外键约束
from sqlalchemy import Column,Integer,String,ForeignKey
class Employees(Base):
tablename='employees'
emp_id=Column(Integer,primary_key=True)
name=Column(String(20))
genda = Column(String(10))
phone = Column(String(11))
dep_id=Column(Integer,ForeignKey('departments.dep_id'))
def __repr__(self):
return "" % self.name
日期
from sqlalchemy import Column,Integer,String,ForeignKey,Date
class salary(Base):
tablename='salary'
id=Column(Integer,primary_key=True)
date=Column(Date) #日期应用
emp_id=Column(Integer,ForeignKey('employees.emp_id'))
basic=Column(Integer)
extra = Column(Integer)
日期插数据
from datetime import date
date1=date(2017,1,1)
bob1=Salary(date=date1,emp_id=4,basic=1000,extra=3000)
基本查询
通过作用于session的query()函数创建查询对象
query()函数可以接收多种参数
Session=sessionmaker(bind=engine)
session=Session()
for instance in session.query(Departments).order_by(Departments.dep_id):
print(instance.dep_id,instance.dep_name)
使用ORM描述符进行查询
返回值是元组
for name,phone in session.query(Employees.name,Employees.phone ): #多字段
print(name,phone)
使用命名元组(即为元组下标命名,方便引用)
查询对象返回的是一个命名元组
名称是类的名字,或是类中属性的名字
for row in session.query(Departments,Departments.dep_name)
print(row.Departments,row.dep_name)
修改显示字段名
显示的字段名可以通过label()函数进行修改
for row in session.query(Departments.dep_name.label('部门')):
print(row.部门)
使用别名
可以为经常使用的类定义别名
from sqlalchemy.orm import sessionmaker,aliased
new_emp=aliased(Employees)
for row in session.query(new_emp,new_emp.name,new_emp.phone).all():
print(row.name,row.phone)
排序
通过order_by()函数可以实现按指定字段排序
for instance in session.query(Departments).order_by(Departments.dep_id):
print(instance.dep_id,instance.dep_name)
提取部分数据
通过“切片”的方式,实现部分数据的提取
new_emp=aliased(Employees)
for row in session.query(new_emp,new_emp.name,new_emp.phone).order_by(new_emp.emp_id)[2:4]:
print(row.name,row.phone)
结果过滤
通过filter()函数实现结果过滤
new_emp=aliased(Employees)
for row in session.query(new_emp,new_emp.name,new_emp.phone).filter(new_emp.name=='bob'):
print(row.name,row.phone)
filter()函数可以叠加使用
new_sal=aliased(Salary)
for row in session.query(new_sal,new_sal.emp_id,new_sal.basic,new_sal.extra).filter(new_sal.extra >=2000).filter(new_sal.extra<10000):
print(row.emp_id)
常用过滤操作符
相等
query.filter(Employees.name=='john')
不相等
query.filter(Employees.name!='john')
模糊查询
query.filter(Employees.name.like('j%'))
in
query.filter(Employees.name.in_(['j','b']))
not in
query.filter(~Employees.name.in_(['j','b']))
字段为空
query.filter(Employees.name.is_(None))
字段不为空
query.filter(Employees.name.isnot(None))
多重条件AND
from sqlalchemy import and_
query.filter(and_(new_sal.basic>=10000,new_sal.extra>=2000))
多重条件or
from sqlalchemy import or_
query.filter(or_(new_sal.basic>=10000,new_sal.extra>=2000))
查询对象返回值
all()返回列表
first()返回结果中的第一条记录
one()取出所有记录,如果不是一条记录则抛出异常
scalar()调用one(),返回第一列的值
new_sal=aliased(Salary)
query= session.query(new_sal)
print(query.all())
聚合
通过count()方法,统计行数
new_sal=aliased(Salary)
query= session.query(new_sal).filter(new_sal.extra<10000)
print(query.count())
多表查询
通过join() 方法实现多表查询
new_emp=aliased(Employees)
new_dep=aliased(Departments)
query=session.query(new_emp.name,new_dep.dep_name).join(new_dep,new_emp.dep_id==new_dep.dep_id)
result=query.all()
print(result)
通过会话的update()方法更新
query=session.query(Departments).filter(Departments.dep_id==8)
query.update({Departments.dep_name:'运营'})
session.commit()
通过会话的字段赋值更新
dep_yy=session.query(Departments).get(8) #get主键
dep_yy.dep_name='运营'
session.commit()
删除记录
通过会话的delete()方法进行记录删除
dep_yy=session.query(Departments).get(8) #get主键
session.delete(dep_yy)
session.commit()
session.close()