python 对象使用

python对象使用

  1. 存储

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    python的数据都保存在内存中,如果断电,内存中数据就会消失.另一方面,python程序运行结束,那么分配给这个程序的内存空间也会清空.为了长期持续存储,python将数据存储在磁盘中.磁盘以文件为单位来存储数据.对于计算机来说,数据本质就是有序的二进制序列,如果以字节为单位,也就是每8位二进制序列为单位,8位的二进制序列正好对应ASCII编码中的一个字符.python借助文本对象来读写文件.

    例如:
    f = open('test.txt','r')
    content = f.read(10)
    content = f.readline()
    content = f.readlines()
    f.close

    f = open('test.txt','w')
    f.write('I like apple\n')
    f.close

    文件操作常常和上下文管理器一起使用,上下文管理器用于规定某个对象的使用范围:一旦进入或者离开该使用范围,则会有特殊的操作被调用.
    例如:
    with open('test.txt','w') as f:
    f.write('hello world !')

    上下文管理器有隶属于它的程序块,当隶属于程序块执行结束时,上下文管理器就会自动关闭文件
    在使用上下文管理器语法时,python会在进入程序块前调用文件对象__enter__()方法,在结束程序块时调用文件对象__exit__()方法.

    自定义上下文管理器:
    class Vow(object):
    def __init__(self,text):
    self.text = text
    def __enter__(self):
    self.text = "I say: " + self.text
    return self
    def __exit__(self,exc_type,exc_value,traceback):
    self.text = self.text + "!"

    with Vow("I am fine") as MyVow:
    print(MyVow.text)

    print(MyVow.text)


    我们能把文本存于文件,但python中最常见的是对象,当程序结束或计算机关机时,这些存在于内存的对象会消失.利用pickle可以将对象保存下来,再存储到磁盘里的文件
    对象存储步骤:
    第一步,我们将对象在内存中的数据直接抓取出来,转换成一个有序的文本,即序列化
    第二步,将文本存入文件
    等到需要时,我们从文件中读出文本,再放入内存,就可以获得原有对象
    例如:
    import pickle
    class Bird(object):
    have_feather = True
    reproduction = 'egg'

    summer = Bird() #创建对象

    方式一:
    pickle_str = pickle.dumps(summer) #序列化对象,将对象转化为字符串形式
    with open('text.pkl','wb') as f: #将内容写入到文件
    f.write(pickle_str)

    方式二:
    with open('text.pkl','wb') as f:
    pickle.dumps(summer,f)

    对象读取步骤:
    第一步,从文件中读取文本
    第二步,将字符串形式的文本转换为对象(注意:在读取对象时,程序中必须已经定义过类)
    例如:
    import pickle
    class Bird(object):
    have_feather = True
    reproduction = 'egg'
    with open('text.pkl','r') as f:
    summer = pickle.loads(f)
    print(summer.reproduction)
  2. 时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    python通过编程来管理时间和日期

    //time包
    例如:
    import time
    print(time.time()) #挂钟时间,单位是秒

    //测试程序运行时间
    import time
    start = time.clock()
    for i in range(1000):
    print(i**2)
    end = time.clock()
    print(end - start)
    注意: clock()在不同计算机上返回值会有所不同,unix系统上,返回的是处理器时间,windows则是挂钟时间

    //sleep()让程序休眠
    import time
    print('start')
    sleep(10)
    print('end')

    //struct_time对象
    import time
    st = time.gmtime() 返回struct_time的UTC时间
    st = time.localtime() 返回struct_time的当地时间
    s = time.mktime(st) 将struct_time转换为挂钟时间

    //datetime包
    datetime由data和time两部分组成:date是指年月日构成的日期,time是指时分秒毫秒构成的一天24小时具体时间
    datetime模块下面有两类: datetime.data和datetime.time类,你也可以调用datetime.datetime类
    例如:
    import datetime
    print(datetime.datetime(2017,6,2,10,5))

    a = datetime.datetime(2017,6,1,10,5)
    b = datetime.datetime(2017,7,10,10,5)
    c = datetime.timedelta(seconds = 600)
    d = datetime.timedelta(weeks = 3)
    print(a + c)
    print(b - d)
    print(a > b)

    //日期格式
    对于包含时间信息的字符串来说,我们可以借助datetime包,把它转换成datetime类的对象
    例如:
    from datetime import datetime
    str = 'output-2017-06-02-101400.txt'
    format = "output-%Y-%m-%d-%H%M%S.txt"
    t = datetime.strptime(str,format)
    print(t)

    将一个datetime对象转换为特定格式的字符串:
    from datetime import datetime
    format = "%Y-%m-%d %H%M%S"
    t = datetime(2017,6,2,10,15)
    print(t.strftime(format))
  3. 正则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    正则表达式的主要功能是从字符串中通过特定的模式,搜索希望找到的内容
    python中使用re来处理正则表达式
    例如:
    import re
    m = re.search("[0-9]","abcd4ef")
    print(m.group(0))

    正则搜索方法:
    m = re.search(pattern,string) #搜索整个字符串,直到发现符合的字符串为止
    m = re.match(pattern,string) #从头开始检查字符串是否符合正则表达式,字符串第一个字符必须符合正则

    正则搜索字符并替换:
    str = re.sub(pattern,replacement,string)

    常用正则:
    re.split() #根据正则表达式分割字符串,并将所有字符串放在一个list表中返回
    re.findall() #根据正则搜索字符串,将所有符合条件的子字符串放在一个list表中返回

    正则表达式:
    * . 任意一个字符
    * a|b 字符a或b
    * [abc] a或b或c一个字符
    * [0-4] 0-4范围内的一个字符
    * [a-f] a-f范围内的一个字符
    * [^m] 非m的一个字符
    * \s 一个空格
    * \S 一个非空格
    * \d 一个数字,等价于[0-9]
    * \D 一个非数字,等价于[^0-9]
    * \w 数字或字母,等价于[0-9a-zA-Z]
    * \W 非数字或字母,等价于[^0-9a-zA-Z]

    正则表示重复符号:
    * * 重复超过0次或更多次
    * + 重复1次或超过1次
    * ? 重复0次或1次
    * {m} 重复m次
    * {m,n} 重复m到n次

    正则位置相关符号:
    * ^ 字符串的起始位置
    * $ 字符串的结尾位置

    正则进一步提取
    * () 用括号()圈起来的正则是表达式的一部分,称为群.一个正则中可以有多个群
    例如:
    import re
    m = re.search("output_(\d{4})","output_2017.txt")
    print(m.group(1))

    m = re.search("output_(?P<year>\d{4})","output_2017.txt")
    print(m.group("year"))
  4. python http通信

    1
    2
    3
    4
    5
    6
    7
    8
    9
    python标准库中的http.client包可用于发出HTTP请求
    例如:
    import http.client
    conn = http.client.HTTPConnection('www.baidu.com')
    conn.request("GET","/")
    respone = conn.getresponse()
    print(response.status,response.reason)
    content = response.read()
    print(content)

TCP 状态

TCP状态

  • TCP三次握手的过程如下:

    1. 主动连接端发送一个SYN包给被动连接端
    2. 被动连接端收到SYN包后,发送一个带ACK和SYN标志的包给主动连接端
    3. 主动连接端发送一个带ACK标志的包给被动连接端,握手动作完成
  • TCP四次挥手的过程如下:

    1. 主动关闭端发送一个FIN包给被动关闭端
    2. 被动关闭端收到FIN包后,发送一个ACK包给主动关闭端
    3. 被动关闭端发送了ACK包后,再发送一个FIN包给主动关闭端
    4. 主动关闭端收到FIN包后,发送一个ACK包,当被动关闭端收到ACK包后,四次挥手动作完成,连接断开

netstat或ss中的TCP状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//获取TCP状态命令
netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ss -ant|awk '{print $1}'|sort|uniq -c

//各个状态说明
* CLOSED 初始(无连接)状态。
* LISTEN 侦听状态,等待远程机器的连接请求
* SYN_SEND 在TCP三次握手期间,主动连接端发送了SYN包后,进入SYN_SEND状态,等待对方的ACK包
* SYN_RECV 在TCP三次握手期间,主动连接端收到SYN包后,进入SYN_RECV状态
* ESTABLISHED 完成TCP三次握手后,主动连接端进入ESTABLISHED状态.此时,TCP连接已经建立,可以进行通信
* FIN_WAIT_1 在TCP四次挥手时,主动关闭端发送FIN包后,进入FIN_WAIT_1状态
* FIN_WAIT_2 在TCP四次挥手时,主动关闭端收到ACK包后,进入FIN_WAIT_2状态
* TIME_WAIT 在TCP四次挥手时,主动关闭端发送了ACK包之后,进入TIME_WAIT状态,等待最多MSL时间,让被动关闭端收到ACK包
* CLOSING 在TCP四次挥手期间,主动关闭端发送了FIN包后,没有收到对应的ACK包,却收到对方的FIN包.此时,进入CLOSING状态
* CLOSE_WAIT 在TCP四次挥手期间,被动关闭端收到FIN包后,进入CLOSE_WAIT状态
* LAST_ACK 在TCP四次挥手时,被动关闭端发送FIN包后,进入LAST_ACK状态,等待对方的ACK包

//主动和被动可能出现的状态
* 主动连接端可能的状态有: CLOSED,SYN_SEND,ESTABLISHED。
* 主动关闭端可能的状态有: FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT
* 被动连接端可能的状态有: LISTEN,SYN_RECV,ESTABLISHED
* 被动关闭端可能的状态有: CLOSE_WAIT,LAST_ACK,CLOSED

postgresql 常用命令

postgrsql 常用命令

  1. 数据库基本查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //显示服务器监听端口号
    select inet_server_port();

    //显示当前数据库
    select current_database();

    //显示当前的userid
    select current_user;

    //显示接受服务器的连接地址
    select inet_server_addr();

    //通过用户{role}连接
    \c - {role}
  2. 查看表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    postgres=# \d+ pg_stat_activity;
    View "pg_catalog.pg_stat_activity"
    Column | Type | Modifiers | Storage | Description
    ------------------+--------------------------+-----------+----------+-------------
    datid | oid | | plain |
    datname | name | | plain |
    pid | integer | | plain |
    usesysid | oid | | plain |
    usename | name | | plain |
    application_name | text | | extended |
    client_addr | inet | | main |
    client_hostname | text | | extended |
    client_port | integer | | plain |
    backend_start | timestamp with time zone | | plain |
    xact_start | timestamp with time zone | | plain |
    query_start | timestamp with time zone | | plain |
    state_change | timestamp with time zone | | plain |
    waiting | boolean | | plain |
    state | text | | extended |
    query | text | | extended |
    View definition:
    SELECT s.datid,
    d.datname,
    s.pid,
    s.usesysid,
    u.rolname AS usename,
    s.application_name,
    s.client_addr,
    s.client_hostname,
    s.client_port,
    s.backend_start,
    s.xact_start,
    s.query_start,
    s.state_change,
    s.waiting,
    s.state,
    s.query
    FROM pg_database d,
    pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, waiting, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port),
    pg_authid u
    WHERE s.datid = d.oid AND s.usesysid = u.oid;

python Django

Python Django install

  1. python virtualenv

    1
    2
    3
    4
    [root@dev ~]# pyenv virtualenv 2.7.13 cmdb
    [root@dev ~]# pyenv virtualenvs
    [root@dev ~]# pyenv activate cmdb
    (cmdb) [root@dev ~]# source deactivate
    1
    2
    3
    [root@dev ~]# pyenv install 3.6.1
    [root@dev ~]# pyenv virtualenv 3.6.1 oeaoo
    [root@dev ~]# pyenv activate oeaoo
  2. django install

    1
    2
    3
    4
    5
    6
    7
    8
    [root@dev ~]# pyenv activate cmdb
    (cmdb) [root@dev ~]# pip install django==1.11.1

    (cmdb) [root@dev ~]# python
    Python 2.7.13 (default, May 22 2017, 11:51:24)
    >>> import django
    >>> print(django.VERSION)
    (1, 11, 1, u'final', 0)
    1
    2
    3
    4
    5
    (oeaoo) [root@dev web]# pip install django==1.11.2
    (oeaoo) [root@dev web]# python
    >>> import django
    >>> print(django.get_version())
    1.11.2

Python Django 开发站点

  1. 建立项目

    1
    2
    3
    4
    5
    6
    7
    8
    9
    (cmdb) [root@dev ~]# django-admin startproject djangosite
    (cmdb) [root@dev ~]# tree djangosite/
    djangosite/
    ├── djangosite
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    (oeaoo) [root@dev oeaoo]# django-admin startproject cmdb
    (oeaoo) [root@dev oeaoo]# tree cmdb/
    cmdb/
    ├── cmdb
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
  2. 建立应用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    (cmdb) [root@dev ~]# cd djangosite/
    (cmdb) [root@dev djangosite]# python manage.py startapp app
    (cmdb) [root@dev djangosite]# tree .
    .
    ├── app
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── djangosite
    │   ├── __init__.py
    │   ├── __init__.pyc
    │   ├── settings.py
    │   ├── settings.pyc
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    (oeaoo) [root@dev cmdb]# python manage.py startapp polls
    (oeaoo) [root@dev cmdb]# tree .
    .
    ├── cmdb
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-36.pyc
    │   │   ├── settings.cpython-36.pyc
    │   │   ├── urls.cpython-36.pyc
    │   │   └── wsgi.cpython-36.pyc
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── db.sqlite3
    ├── manage.py
    └── polls
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py
  3. 基本视图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    * 建立路由响应函数
    (cmdb) [root@dev djangosite]# vim app/views.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.shortcuts import render
    # Create your views here.
    from django.http import HttpResponse
    def welecome(request):
    return HttpResponse("<h1>Welecome to my website!</h1>")

    * 通过URL映射将用户的HTTP访问与该函数绑定起来
    (cmdb) [root@dev djangosite]# vim app/urls.py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
    url(r'',views.welecome)
    ]

    * 在项目URL文件中的urlpatterns参数中增加一项,声明对应用app中的ruls.py文件的引用
    (cmdb) [root@dev djangosite]# vim djangosite/urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from django.conf.urls import include #新增
    urlpatterns = [
    url(r'^app/', include('app.urls')), #新增
    url(r'^admin/', admin.site.urls),
    ]
  4. 内置web服务器

    1
    2
    3
    4
    5
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# python manage.py runserver 0.0.0.0:8080

    浏览器中输入: http://127.0.0.1:8080/app/ 进行检查
  5. 摸类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    * 配置项目INSTALLED_APPS
    要在djangosite项目的setting.py中告诉Django需要安装应用app中的模型,则方法是找到djangosite/setting.py文件,找到INSTALLED_APPS数组,在其中添加应用app的Config类
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# vim djangosite/settings.py
    INSTALLED_APPS = [
    'app.apps.AppConfig', #新增
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    ]
    注意: 上面声明的是djangosite/app/apps.py中自动生成的AppConfig类

    * 模型定义
    定义一个模型类Moment用来定义信息发布表
    (cmdb) [root@dev djangosite]# vim app/models.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models #所有的模型类必须继承自它
    # Create your models here.
    class Monment(models.Model): #定义了models.Model的子类Monment
    content = models.CharField(max_length=200)
    user_name = models.CharField(max_length=20)
    kind = models.CharField(max_length=20)

    * 生成数据移植文件
    生成数据移植文件是指将models.py中定义的数据表转换成数据库生成脚本的过程
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# python manage.py makemigrations app
    Migrations for 'app':
    app/migrations/0001_initial.py
    - Create model Monment

    * 将数据移植文件应用到数据库
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# python manage.py migrate
    Operations to perform:
    Apply all migrations: admin, app, auth, contenttypes, sessions
    Running migrations:
    Applying app.0001_initial... OK
    Applying app.0002_auto_20170523_0338... OK
    在命令执行过程中将检查djangosite/app/migrations目录中的所有文件,逐步使历次生成的移植文件生效
  6. 表单视图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    设计和开发信息录入页面:提供输入界面,让用户输入名字,文本信息内容和选择消息类型.用户提交后网页自动设置该信息的时间并保持到数据库中

    * 定义表单类
    (cmdb) [root@dev djangosite]# pwd
    /root/djangosite
    (cmdb) [root@dev djangosite]# vim app/forms.py
    # -*- coding: utf-8 -*-
    from django.forms import ModelForm #引入django表单类的基类
    from app.models import Moment #引入models定义的Moment类,以便后面表单中关联Moment类

    class MomentForm(ModelForm): #定义表单类MomentForm类,继承ModelForm.
    class Meta: #定义子类Meta,声明与本表单关联的模型类及其字段
    model = Moment
    fields = '__all__'

    * 修改模型类
    为了使用户能以单选的方式设置消息类型,则需要在models.py文件中定义单选枚举值,并与模型类Moment关联
    (cmdb) [root@dev djangosite]# vim app/models.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models
    # 声明元组用于设置消息类型枚举项
    KIND_CHOICES = (
    ('python技术','python技术'),
    ('数据库技术','据库技术'),
    ('个人中心','个人中心'),
    ('其它','其它'),
    )
    # Create your models here.
    class Monment(models.Model):
    content = models.CharField(max_length=300)
    user_name = models.CharField(max_length=20,default='匿名')
    kind = models.CharField(max_length=20,choices=KIND_CHOICES,default=KIND_CHOICES[0])

    * 开发模板文件
    模板是python web框架中用于产生HTML,XML等文本格式文档的术语
    模板文件本身也是一种文本文件,开发者需要手工对齐编辑开发
    //创建模板存放目录
    (cmdb) [root@dev djangosite]# mkdir app/templates
    //创建模板文件
    (cmdb) [root@dev djangosite]# vim app/templates/moments_input.html
    <!DOCTPYPE html>
    <html>
    <head>
    <title>消息录入界面</title>
    </head>
    <body>
    <form action="?" method="post">
    <fieldset>
    <legend>请输入并提交</legend>
    {{form.as_p}}
    <input type="submit" value="submit" />
    </fieldset>
    </form>
    </body>
    </html>

    * 开发视图(使得表单类和页面模板衔接起来)
    (cmdb) [root@dev djangosite]# vim app/views.py
    # -*- coding: utf-8 -*-
    import os
    from __future__ import unicode_literals
    from app.forms import MomentForm
    from django.shortcuts import render
    from django.http import HttpResponse
    from django.core.urlresolvers import reverse
    def welcome(request):
    return HttpResponse("<h1>Welecome to my website!</h1>")
    def monments_input(request):
    if request.method == 'POST':
    form = MomentFrom(request.POST)
    if form.is_valid():
    moment = form.save()
    moment.save()
    return HttpResponseRedirect(reverse("app.views.welcome"))
    else:
    form = MomentFrom()
    PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    return render(request,os.path.join(PROJECT_ROOT,'app/templates','moments_input.html',{'form': form}))

    * 增加视图函数路由映射
    (cmdb) [root@dev djangosite]# vim app/urls.py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
    url(r'moments_input',views.moments_input,name='moments_input'),
    url(r'',views.welcome,name='welcome'),
    ]
  7. Django模型层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    Django模型层是Django框架自定义的一套独特的ORM技术.

    使用Django模型开发的首要任务是定义模型类及其属性.每个模型类都可以被映射为数据库中的一个数据表,而类型属性被定义为数据字段,除此之外,数据库表的主键,外键,约束也通过类的属性完成定义

    * 模型类定义
    from django.db import models

    class ModelName(models.Model):
    field1 = models.XXField(...)
    field2 = models.XXField(...)

    class Meta:
    db_table = ...
    other_metas = ...

    解析:
    * 所有的Django模型继承自django.db.models.Model类
    * 通过其中的类属性定义模型字段,模型字段必须是某种models.XXField类型
    * 通过模型类中的Meta子类定义模型元数据,比如数据库表名,数据默认排序等

    Meta类的属性名由Django预定于,通用属性如下:
    * abstract True/False,标识是否为抽象基类
    * app_label 定义本类所属的应用,例如: app_label="myapp"
    * db_table 映射的数据表名(如果未定义,则默认生成数据表,表名为"应用名_模型名")
    * db_tablespace 映射表空间名(表空间在oracle和postgresql中存在)
    * default_related_name 定义模型的反向关系引用名称,默认与模型名一样
    * get_latest_by 定义按哪个字段值排列以获得模型开始或结束记录,本属性值通常指向一个日期或整型的模型字段
    * managed True/False,定义Django的manage.py命令行工具是否管理本模型
    * order_with_respect_to 定义模型可以按照某外键引用关系排序
    * ordering 本模型记录的默认排序字段,可以设置多个字段,默认以升序排序,降序需要在前面加负号(-)
    * default_permissions 模型操作权限(add,change,delete)
    * proxy True/False,本模型及所有继承自本模型的子模型是否为代理模型
    * require_db_features 定义底层数据库所必须具备的特性
    * require_db_vendor 定义底层数据库类型(SQLite,PostgreSQL,MySQL,Oracle)
    * unique_together 用来设置不重复的字段组合,必须唯一
    * index_together 定义联合索引的字段,可以设置多个
    * verbose_name 指明一个易于理解和表述的单数形式的对象名称
    * verbose_name_plural 指明一个易于理解和表述的复数形式对象名称

    * 普通字段类型
    普通字段类型中除外键关系外的数据字段属性.
    所有的字段属性必须继承自抽象类django.db.models.Field,开发可以自定义继承自该类的字段类型

    预定于类型:
    * AutoField 一个自动递增的整形字段,添加记录时会自动增长(充当主键)
    * BigIntegerField 64位整型字段
    * BinaryField 二进制数据字段,只能通过bytes对其进行赋值
    * BooleanField 布尔字段,对应html标签"<input type="checkbox">"
    * CharField 字符串字段,用于较短的字符串,对应于html标签"<input type="text">"
    * TextField 大容量字段,对应于html标签是多行编辑框"<textarea>"
    * CommaSeparatedIntegerField 用于存放逗号分隔的整数值
    * DateField 日期字段,对应于html标签是"<input type="text">"
    * DateTimeField 类似于DateField,但同时支持于时间的输入
    * DurationField 存储时间周期
    * EmailField 一个带有检查Email合法性的CharField
    * FileField 一个文件上传字段
    * FilePathField 按目录限制规则选择文件,定义本字段时必须传入参数path,用于限定目录
    * FloatField 浮点型字段
    * ImageField 类似FileField,同时校验上传对象是否是一个合法图片
    * IntegerField 用于保存一个整数
    * IPAddressField 一个字符串形式的IP地址
    * NullBooleanField 类似BooleanField,但多出一个None选项
    * PhoneNumberField 带有美国风格的电话号码校验(xxx-xxx-xxxx)
    * PositiveIntegerField 只能输入非负数的IntegerField
    * SlugField 只包含字母,数字,下划线和连字符输入字段,用于URL
    * SmallIntegerField 类似IntegerField,但只有较小的输入范围
    * TimeField 时间字段,但只能表达和输入时间
    * URLField 用于保存URL
    * USStateField 美国州名缩小,由两个字段组成
    * XMLField XML字符字段

    * 字段类型参数
    每个字段类型都有一些特定的HTML标签和表单验证参数.但同时也有一些每个字段都可以设置的公共参数
    公共参数:
    * null 定义是否允许相对应的数据库字段为null,默认为False
    * blank 定义字段是否可以为空.blank用于字段HTML表单验证.null用于数据库中的非空约束
    * choices 定义字段可选值
    * default 定义默认值
    * help_text HTML页面中输入控件的帮助信息
    * primary_key 定义字段是否为主键
    * unique 定义字段数据是否是唯一
    * 无名参数,人性化设置

    * 基本查询
    Django有两种过滤器用于筛选数据:
    * filter(**kwargs) 返回符合筛选条件的数据集
    * exclude(**kwargs) 返回不符合筛选条件的数据集
    * 多个filter和exclude可以组合在一起使用

    * 数据保存和删除
    Django定义了一个统一的方法"save()",用于完成模型的Insert和update操作
    在执行模型实例Save()时,Django会根据模型的主键,判断记录是否存在,存在则Update操作,不存在则Insert操作

    Django提供了delete()方法用于删除记录,该方法即可以用于数据集,又可以用于单条记录

    * 关系操作
    利用数据表之间的关系进行数据建模和业务开发是关系数据库最主要的功能

    //一对一关系
    一对一关系通过在两个表之间定义相同的主键来完成(OneToOneField)
    //一堆多关系
    一对多关系通过"附表"中设置到"主表"的外键引用来完成(models.ForeignKey定义外键)
    //多对多关系
    多对多关系通过建立一个中间关系表来完成,该中间表定义了到两个主表的外键

    * 面向对象ORM
    Django支持三种风格的模型继承:
    * 抽象类继承
    父类继承自models.Model,但不会在底层数据库中生成相应的数据表.父类的属性列存储在其子类的数据表中
    * 多表继承
    多表继承的每个模型类都在底层数据库中生成相应的数据表管理数据
    * 代理模型继承
    父类用于在底层数据库中管理数据表,而子类不顶用数据列,只定义查询数据集的排序方式等元数据

postgresql 数据库管理

postgrsql 数据库管理

  1. postgrsql登录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // postgresql 登录和退出
    -bash-4.2$ psql -U postgres -d postgres
    postgres=# \q

    注意: 如果登录PG时,只指定了用户"psql -U postgres",未指定数据库"-d postgres",默认数据库会跟用户名一致(也就是说默认连接的数据库名='postgres')

    //切换用户进行连接
    postgres=# \c - role

    //切换到数据库
    postgres=# \c database
  2. 连接管理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //查看活动连接表,以及其进程ID
    postgres=# select * from pg_stat_activity;
    或者:
    postgres=# \x
    postgres=# select * from pg_stat_activity;
    postgres=# \x

    //取消连接上的活动查询(该操作不会终止连接本身(不会中断session,事务回滚))
    postgres=# select pg_cancel_backend(12950);

    //终止连接(中断session)
    postgres=# select pg_terminate_backend(12950);

    //批量删除
    postgres=# select pg_terminate_backend(pid) from pg_stat_activity where usename = 'some_role';
  3. 创建可登录角色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    角色相当于岗位,用户就是具体的人.
    Postgresql中没有区分用户和角色,"create user""create role"的别名,这两个命令几乎是完全相同的,唯一的区别是"create user"命令创建的用户默认带有LOGIN属性,而"create role"命令创建的用户默认不带LOGIN属性
    我们建议使用"create role"来创建用户!

    //创建角色
    postgres=# create role penn;

    //删除角色
    postgres=# drop role penn;

    //查看角色
    postgres=# \du
    或者
    postgres=# select * from pg_roles;
  4. 为角色授权

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //为角色授和取消LOGIN权限
    postgres=# alter role penn login;
    postgres=# alter role penn nologin;

    //为角色授权和取消SUPERUSER权限
    postgres=# alter role penn superuser;
    postgres=# alter role penn nosuperuser;

    //为角色授权和取消CREATEDB
    postgres=# alter role penn createdb;
    postgres=# alter role penn nocreatedb;

    //为角色授权和取消CREATEROLE
    postgres=# alter role penn createrole;
    postgres=# alter role penn nocreaterole;

    //为角色授权和取消REPLICATION
    postgres=# alter role penn replication;
    postgres=# alter role penn noreplication;
  5. 创建角色并授权

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //创建角色并授权LOGIN
    postgres=# create role penn login;

    //创建角色并授权SUPERUSER
    postgres=# create role penn superuser;

    //创建角色并授权CREATEDB
    postgres=# create role penn createdb;

    //创建角色并授权CREATEROLE
    postgres=# create role penn createrole;

    //创建角色并授权REPLICATION
    postgres=# create role penn replication login;
  6. 创建角色,授权,并为角色设置密码

    1
    2
    3
    4
    5
    6
    //创建角色并授权LOGIN,并设置密码
    postgres=# create role penn login password '123456';
    或者:
    postgres=# create role penn;
    postgres=# alter role penn login;
    postgres=# alter role penn password '123456'
  7. 创建组角色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    //创建组角色
    postgres=# create role group_1 inherit;
    inherit 表示组角色group_1内的任何成员都会自动继承其除"超级用户权限"之外的所有权限
    noinherit 表示禁止组角色group_1将其权限授予其成员角色

    //授权组角色
    postgres=# alter role group_1 login;

    //将组角色权限授权给组成员(将用户加入到组角色中,继承权限)
    postgres=# grant group_1 to penn;

    //撤销组角色权限
    postgres=# revoke group_1 from penn;

    //一个角色成员使用组角色的权限
    两种方式:
    方式一: 每个组成员都可以用"SET ROLE"命令将自己临时"变成"该组成员,此后再创建的任何对象的所有者将属于该组,而不是原有的登录用户
    方式二: 拥有INHERIT属性的角色成员自动继承它们所属角色的权限

    postgres=# create role penn inherit;
    postgres=# create role haha noinherit;
    postgres=# create role xixi noinherit;
    postgres=# grant haha to penn;
    postgres=# grant xixi to haha;

    用用角色penn与数据库建立连接,那么该会话同时拥有角色penn和角色haha的权限(inherit权限继承),然而赋予角色xixi的权限在会话中不可用,因为角色penn只是角色xixi的一个间接成员,它是通过haha角色间接传递过来的,这样xixi权限无法被penn用户继承

    如果想让penn继承xixi权限,我们在会话中这么操作:
    set role haha;
    set role xixi;

    如果想会话恢复原有角色权限,我们在会话中这么操作:
    set role penn;
    or:
    set role none;
    or:
    reset role;

postgresql 数据库对象

postgresql 数据库对象

  1. 服务

    1
    Postgresql是一种服务(守护进程)安装的.多个Postgresql服务可以运行于同一台服务器上,它们的端口不能重复,也不能共享同一个数据存储目录
  2. database

    1
    每个Postgresql服务可以包含多个独立的database
  3. schema

    1
    2
    3
    database的下一层逻辑结构就是schema.
    大多数对象是隶属于某个schema的,然后schema又隶属于某个database
    在创建database时,postgresql会默认自动为其创建一个名为public的schema
  4. catalog

    1
    2
    3
    4
    catalog是系统级的schema,用于存储系统函数和系统元数据
    每个database创建好后,默认会有两个catalog:
    * 一个名为pg_catalog,用于存储Postgresql系统自带的函数,表,系统视图,数据类型转换器以及数据类型定义等元数据
    * 一个是information_schema,用于存储ANSI标准中所需求提供的元数据查询视图
  5. 变量

    1
    变量是Postgresql统一配置机制(GUC)的一部分,是可以在多个级别设置的各种选项,这些级别包括服务级别,database级别以及其它级别
  6. 扩展包

    1
    2
    3
    开发人员可以通过该机制将一组相关的函数,数据类型,数据类型转换器,用户自定义索引,表以及GUC等对象打包成一个功能扩展包,该扩展包可以整体安装或整体删除
    安装扩展包可以指定到对应的database,而不必对所有database都安装一遍
    安装扩展包可以指定安装到哪个schema,若不指定,会默认安装到public schema中
  7. 1
    2
    3
    4
    5
    postgresql中,表先属于某个schema,schema又属于某个database,这样就构成了一个三级存储结构
    postgresql的表支持两种强大的功能:
    * 表继承,即一张表可以有父表,又可以有子表
    * 创建一张表的同时,系统会自动为此表创建一种对应的自定义数据类型.
    换句话说,你可以将某个完整的数据结构定义为一张表,然后将该表用作另一个表的一个列
  8. 外部表和外部数据封装器

    1
    2
    3
    外部表是一些虚拟表,通过它们可以直接在本地数据库中访问来自外部数据源的数据.只要数据映射关系配置正确,那么外部表的用法与普通表没有任何区别.
    外部表支持映射到以下类型的数据源:CSV文件,另一个服务器的Postgresql表,SQL Server,Oracle这些异构数据库中的表,redis这样的nosql数据库
    外部表映射关系的建立是通过配置外部数据封装器(FDW)实现的.FDW是Postgresql和外部数据源之间的"桥梁",可实现两边数据的互联互通
  9. 表空间

    1
    2
    3
    表空间是用于存储数据的物理空间
    Postgresql将用于物理存储的表空间和用于逻辑存储的schema分开管理,二者之间无耦合关系.
    这样就很容易在不影响业务逻辑的情况下,将database甚至是单张表和索引在不同物理驱动器之间进行移动
  10. 视图

    1
    大多数关系型数据库都支持视图,通过视图可以大大简化复杂的查询逻辑,另外也可以通过对视图执行更新操作来修改其基表数据
  11. 函数

    1
    2
    postgresql中函数执行后的返回结果可以是一个标量值或几个记录集
    可以在函数中对表数据进行修改,其他数据库对于这种会修改表记录的函数一般称为存储过程
  12. 内置编程语言

    1
    2
    函数是以过程化语言(PL)编写的
    Postgresql默认支持三种内置编程语言: SQL,PL/pgSQL,C语言
  13. 运算符

    1
    运算符本质上是符号化的已命名函数,它需要一个或两个实参,底层有一个相应的函数来实现其运算逻辑
  14. 数据类型

    1
    Postgresql支持常见数据类型:整型,字符型,数组等等,同时还支持符合数据类型
  15. 数据类型转换器

    1
    2
    cast是数据类型转换器,就是将一种数据类型转换为另一种类型工具.
    转换器在其底层其实是通过调用函数来实现真正的转换逻辑的,Postgresql的独到之处在于支持用户自定义转换器,这样就可以改变系统默认的转换逻辑
  16. 序列

    1
    2
    3
    序列控制serial数据类型的自动递增
    在Postgresql中定义serial列时,postgresql会自动创建序列,但你很容易改变初始值,增量和下一个值
    因为序列是独立对象,索引多个表可以共用一个序列对象
  17. 行或记录

    1
    2
    行或记录这两个术语可以互换
    在Postgresql中,记录 这个概念可以脱离表独立存在
  18. 触发器

    1
    2
    触发器机制可以实现对数据修改事件的捕获,并在之后触发用户自定义操作行为
    触发器的触发时机是可实现的,可以是语句级触发或者记录级触发,可以是修改前触发也可以是修改后触发
  19. 规则

    1
    2
    规则是一种能够将一种动作替换为另一种动作的机制
    Postgresql内部就是使用此机制来实现视图的

postgresql yum install

postgresql yum install

  1. open postgresql yum repo

    1
    2
    [root@dev ~]# rpm -ivh https://download.postgresql.org/pub/repos/yum/9.3/redhat/rhel-7-x86_64/pgdg-centos93-9.3-3.noarch.rpm
    [root@dev ~]# make cache
  2. postgresql install

    1
    [root@dev ~]# yum -y install postgresql93-server postgresql93-contrib
  3. postgresql init

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@dev ~]# /usr/pgsql-9.3/bin/postgresql93-setup initdb

    [root@dev ~]# tail -1 /etc/passwd
    postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash

    [root@dev ~]# ls -l /var/lib/pgsql/9.3/
    total 8
    drwx------ 2 postgres postgres 6 May 10 07:25 backups
    drwx------ 16 postgres postgres 4096 May 22 11:07 data
    -rw------- 1 postgres postgres 1330 May 22 11:04 initdb.log
  4. postgresql 修改配置文件

    1
    2
    3
    [root@dev ~]# vim /var/lib/pgsql/9.3/data/postgresql.conf
    listen_addresses = '*'
    port = 5432
  5. postgresql 启动

    1
    2
    3
    [root@dev ~]# systemctl start postgresql-9.3
    [root@dev ~]# systemctl status postgresql-9.3
    [root@dev ~]# systemctl enable postgresql-9.3
  6. postgresql 登录,修改密码

    1
    2
    3
    4
    [root@dev ~]# su - postgres
    -bash-4.2$ psql -U postgres
    postgres=# alert user postgres with password 'postgres'
    postgres-# \q

wireshark use

wireshark 常用操作

  1. 数据包过滤
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //常见过滤条件
    ip.addr==1.1.1.1 过滤某个IP地址
    ip.src==1.1.1.1 过滤源地址
    ip.dst==1.1.1.1 过滤目标地址

    tcp.port==80 过滤端口
    tcp.dstport==80 过滤目标端口
    tcp.srcport==80 过滤源端口

    http 过滤http协议
    http.request.method=="GET" 过滤get包
    http.request.method=="POST" 过滤post包


    //组合过滤条件
    ip.src==1.1.1.1 and http
    tcp.srcport==38364 || tcp.dstport==38364

kernel 共享内存

kernel 共享内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
当我们启动程序的时候,有时候发现程序启动失败,经检查日志,发现程序中的内存超出内存限制.

//内核的 shmall 和 shmmax 参数
SHMMAX参数:
置了最大的内存segment的大小(这个设置的比SGA_MAX_SIZE大比较好)
Linux进程可以分配的单独共享内存段的最大值.一般设置为内存总大小的一半.这个值的设置应该大于SGA_MAX_TARGET或MEMORY_MAX_TARGET的值,因此对于安装Oracle数据库的系统,shmmax的值应该比内存的二分之一大一些.

SHMMIN参数:
最小的内存segment的大小
整个系统的内存segment的总个数.设置系统级最大共享内存段数量.Oracle10g推荐最小值为4096,可以适当比4096增加一些

SHMSEG参数:
每个进程可以使用的内存segment的最大个数

SHMALL参数:
全部允许使用的共享内存大小,shmmax是单个段允许使用的大小.这两个可以设置为内存的90%.例如 16G 内存,16*1024*1024*1024*90% = 15461882265,shmall 的大小为 15461882265/4096(getconf PAGESIZE) = 3774873

shmall设置共享内存总页数.这个值太小有可能导致数据库启动报错.很多人调整系统内核参数的时候只关注SHMMAX参数,而忽略了SHMALL参数的设置

//配置信号灯(semphore)的参数
信号灯semaphores是进程或线程间访问共享内存时提供同步的计数器

SEMMSL参数:
设置每个信号灯组中信号灯最大数量,推荐的最小值是250.对于系统中存在大量并发连接的系统,推荐将这个值设置为PROCESSES初始化参数加10

SEMMNI参数:
设置系统中信号灯组的最大数量.Oracle10g和11g的推荐值为142

SEMMNS参数:
设置系统中信号灯的最大数量.操作系统在分配信号灯时不会超过LEAST(SEMMNS,SEMMSL*SEMMNI).事实上,如果SEMMNS的值超过了SEMMSL*SEMMNI是非法的,因此推荐SEMMNS的值就设置为SEMMSL*SEMMNI.Oracle推荐SEMMNS的设置不小于32000,假如数据库的PROCESSES参数设置为600,则SEMMNS的设置应为:
SQL> select (600+10)*142 from dual;
(600+10)*142
------------
86620

SEMOPM参数:
设置每次系统调用可以同时执行的最大信号灯操作的数量.由于一个信号灯组最多拥有SEMMSL个信号灯,因此有推荐将SEMOPM设置为SEMMSL的值.Oracle验证的10.2和11.1的SEMOPM的配置为100

通过下面的命令可以检查信号灯相关配置:
# cat /proc/sys/kernel/sem
250 32000 100 128
对应的4个值从左到右分别为SEMMSL、SEMMNS、SEMOPM和SEMMNI

//修改/etc/sysctl.conf
kernel.shmmax=15461882265
kernel.shmall=3774873
kernel.msgmax=65535
kernel.msgmnb=65535

执行 sysctl -p
使用 ipcs -l 看结果
使用 ipcs -u 可以看到实际使用的情况