docker-compose运行jenkins集成sonarqube代码质量检测

  • 192.168.0.141 jenkins

  • 192.168.0.142 sonarqube

本实例用到2台机器,一台机器里面跑着jenkins服务,一台机器为sonarqube服务

jenkins服务部署这里就不做多的讲解,可以采用docker-compose部署,也可以单独部署,博主采用docker-compose部署的jenkins,我们在另外一台机器部署一个sonarqube服务,这里我们用mysql5.6的镜像和sonarqube的最新版的镜像镜像compose编排部署。

这里编排的是3个服务在一起了,有需要可以自行进行拆分

请参考博主开源项目:https://github.com/lizibin/docker-jenkins-sonarqube

1、拉取博主的项目,即可成功运行jenkins和sonarqube的代码质量检测

我们可以访问主机ip+9000端口访问到页面

未分类

2、这里我们还需要再jenkins进行配置一下插件,才可以自动分析代码质量

未分类

找到这个插件安装好这个插件就开始配置

3、配置jenkins 进入系统配置

未分类

继续配置Global Tool Configuration

未分类

然后我们就可以建立一个自由风格的项目来分析代码了

4、创建项目,需要勾上

未分类

未分类

修改Analysis properties

未分类

就可以开始构建了

5、构建完毕我们可以去9000端口查看页面详情

未分类

使用 Jenkins 自动化发布 PHP 项目

什么是 Jenkins

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

使用 Docker 安装 Jenkins

避免装环境的折腾, 直接使用 docker-compose 安装,具体如何安装在 Docker 快速搭建 LNMP 环境 已经描述了

docker-compose.yml

jenkins:
  image: jenkins:latest
  ports:
    - "8080:8080"
  volumes:
      - ./jenkins:/var/jenkins_home:rw

注意:volumes 配置 jenkins 目录映射到本地

docker-compose up -d 

# 等待下载镜像,创建容器
Creating dnmp_jenkins_1    ... done
# 安装就这么简单

访问 8080 端口,进入初始化页面

访问: http://localhost:8080/

首次打开,需要输入秘钥,根据提示,可以在对应的目录 /jenkins/secrets 找到该文件
设置登录用户名密码后,进入几分钟的初始化过程…

未分类

配置自动化构建发布

配置远程服务器 SSH

菜单 -> 系统管理 -> 系统设置 -> SSH Servers

未分类

如图,是我配置的内容

未分类

Remote Directory 这个配置很关键,表示构建时的相对目录。这里我配置 “/“
配置完成后,最好 Test Configuration , 返回 Success 就表示成功!

新建发布项目

填写项目名称如, test
并选择项目类型,这里我选择”自由风格项目”

未分类

General

选择对应项目路径,我使用 GitHub project

未分类

源码管理

使用 git 源码仓库管理

未分类

构建

这里是最关键的,你可以打包源码发布到对应的服务器之上

未分类

  • Source files 表示打包好的源文件
  • Remote directory 表示你需要将源文件上传的远程路径(这个路径相对于 SSH 配置目录)
  • Exec command 上传完成后,执行的命令( hexo g 这个是我发布博客时的构建命令)

立即构建

选择对应的项目,点击立即构建

未分类

在构建执行状态中,可以点击 console output 看到构建的过程信息

未分类

使用 Supervisor 管理服务器后台进程

Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。

之所以使用 Supervisor,是因为服务器的 MongoDB 进程偶尔会 Crash,需要确保让它在挂掉后自动重启确保服务正常。

0x1 安装

直接使用 pip 进行安装:

$ sudo pip install supervisor

# 可能你会收到类似的报错:Supervisor requires Python 2.4 or later but does not work on any version of Python 3.  You are using version 3.4.3 (default, Oct 28 2017, 20:59:04)
# 可以手动安装新版 Supervisor,它支持 Python3:

$ pip install git+https://github.com/Supervisor/supervisor

# 设置环境变量:
$ vim ~/.bash_profile

在后面补充: PATH=$PATH:$HOME/bin:/usr/local/python/bin

$ source ~/.bash_profile

0x2 配置

$ echo_supervisord_conf > /etc/supervisord.conf

打开配置文件:

$ vim /etc/supervisord.conf

[unix_http_server]
file=/tmp/supervisor.sock   ; UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ; socket 文件的 mode,默认是 0700
;chown=nobody:nogroup       ; socket 文件的 owner,格式: uid:gid
;username=user              ; default is no username (open server)
;password=123               ; default is no password (open server)

;[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
;port=127.0.0.1:9001        ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
;username=user              ; 登录管理后台的用户名
;password=123               ; 登录管理后台的密码

[supervisord]
logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ; 日志文件大小,超出会 rotate,默认 50MB
logfile_backups=10           ; 日志文件保留备份数量默认 10
loglevel=info                ; 日志级别,默认 info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ; pid 文件
nodaemon=false               ; 是否在前台启动,默认是 false,即以 daemon 的方式启动
minfds=1024                  ; 可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ; 可以打开的进程数的最小值,默认 200

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord

;包含其他的配置文件
[include]
files = relative/directory/*.ini    ; 可以是 *.conf 或 *.ini

0x3 配置需要管理的进程

这里以添加 MongoDB 进程为例,首先修改 supervisord.conf:

$ vim supervisord.conf

# 找到最后一行,并取消注释和添加:
[include]
files = /etc/supervisor/*.conf

$ mkdir /etc/supervisor
$ cd /etc/suervisor
$ vim mongodb.conf

# 填入以下内容:

[program:mongodb]
command =  /usr/bin/mongod -port 27017 --dbpath /vr/lib/mongo
autostart = true     ; 在 supervisord 启动的时候也自动启动
startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true   ; 程序异常退出后自动重启
startretries = 3     ; 启动失败自动重试次数,默认是 3

0x4 启动 Supervisor

Supervisor 有两个主要的组成部分:

  1. supervisord,运行 Supervisor 时会启动一个进程 supervisord,它负责启动所管理的进程,并将所管理的进程作为自己的子进程来启动,而且可以在所管理的进程出现崩溃时自动重启。

  2. supervisorctl,是命令行管理工具,可以用来执行 stop、start、restart 等命令,来对这些子进程进行管理。

$ supervisord -c /etc/supervisord.conf
$ supervisorctl -c /etc/supervisord.conf status

> mongodb       RUNNING   pid 2366, uptime 0:01:00

未分类

0x5 可视化管理进程

$ vim /etc/supervisord.conf

# 取消注释和更改设置
[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
port=0.0.0.0:8080          ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
username=user              ; 登录管理后台的用户名
password=123               ; 登录管理后台的密码

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=http://0.0.0.0:8080    ; 通过 HTTP 的方式连接 supervisord

通过浏览器打开网站 url:8080,输入帐号密码,可以在网页中查看进程:

未分类

0x6 开机自启动 Supervisor

Linux 在启动的时候会执行 /etc/rc.local 里面的脚本,所以只要在这里添加执行命令就可以:

# 如果是 Centos 添加以下内容
/usr/bin/supervisord -c /etc/supervisord.conf

# 以上内容需要添加在 exit 命令前,而且由于在执行 rc.local 脚本时,PATH 环境变量
# 未全部初始化,因此命令需要使用绝对路径。可以使用一下命令查看绝对路径:

$ sudo find / -name supervisord
> /usr/local/python/bin/supervisord

所以要改下路径:
/usr/local/python/bin/supervisord -c /etc/supervisord.conf

0x7 常见问题

在启动 supervisorctl 的时候可能会接受到 refuse connection 的报错,解决办法:

# 找到 supervisor.sock 的地址
$ find / -name supervisor.sock

# unlink 掉它,*** 换成真实地址
$ unlink /***/supervisor.sock

还遇到了另外一个问题,在 supervisor 运行一段时间后,web 端会访问不了,在后台企图通过 supervisorctl -c /etc/supervisord.conf 登录,发现还是报 refuse connection 的错误,还有

Error: Another program is already listening on a port that one of our HTTP servers is configured to use.  Shut this program down first before starting supervisord. 

尝试将[supervisorctl] 里面的属性 serverurl 修改成 unix 前缀,如 unix:///tmp/supervisord.sock,过一段时间再做观察。

python(sqlalchemy基本使用)

下面就开始让你见证orm的nb之处,盘古开天劈地之前,我们创建一个表是这样的

CREATE TABLE user (
    id INTEGER NOT NULL AUTO_INCREMENT,
    name VARCHAR(32),
    password VARCHAR(64),
    PRIMARY KEY (id)
)

这只是最简单的sql表,如果再加上外键关联什么的,一般程序员的脑容量是记不住那些sql语句的,于是有了orm,实现上面同样的功能,代码如下

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
engine = create_engine("mysql+pymysql://root:alex3714@localhost/testdb",
                                    encoding='utf-8', echo=True)
Base = declarative_base() #生成orm基类
class User(Base):
    __tablename__ = 'user' #表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
Base.metadata.create_all(engine) #创建表结构

你说,娘那个腚的,并没有感觉代码量变少啊,呵呵, 孩子莫猴急,好戏在后面

Lazy Connecting
The Engine, when first returned by create_engine(), has not actually tried to connect to the database yet; that happens only the first time it is asked to perform a task against the database.

除上面的创建之外,还有一种创建表的方式,虽不常用,但还是看看吧

http://www.cnblogs.com/alex3714/articles/5978329.html#

事实上,我们用第一种方式创建的表就是基于第2种方式的再封装。

最基本的表我们创建好了,那我们开始用orm创建一条数据试试

Session_class = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
Session = Session_class() #生成session实例
user_obj = User(name="alex",password="alex3714") #生成你要创建的数据对象
print(user_obj.name,user_obj.id)  #此时还没创建对象呢,不信你打印一下id发现还是None
Session.add(user_obj) #把要创建的数据对象添加到这个session里, 一会统一创建
print(user_obj.name,user_obj.id) #此时也依然还没创建
Session.commit() #现此才统一提交,创建数据

我擦,写这么多代码才创建一条数据,你表示太tm的费劲了,正要转身离开,我拉住你的手不放开,高潮还没到。。

查询

my_user = Session.query(User).filter_by(name="alex").first()
print(my_user)

此时你看到的输出是这样的应该

<__main__.User object at 0x105b4ba90>

我擦,这是什么?这就是你要的数据呀, 只不过sqlalchemy帮你把返回的数据映射成一个对象啦,这样你调用每个字段就可以跟调用对象属性一样啦,like this..

print(my_user.id,my_user.name,my_user.password)
输出
1 alex alex3714

不过刚才上面的显示的内存对象对址你是没办法分清返回的是什么数据的,除非打印具体字段看一下,如果想让它变的可读,只需在定义表的类下面加上这样的代码

def __repr__(self):
    return "<User(name='%s',  password='%s')>" % (
        self.name, self.password)

修改

my_user = Session.query(User).filter_by(name="alex").first()
my_user.name = "Alex Li"
Session.commit()

回滚

my_user = Session.query(User).filter_by(id=1).first()
my_user.name = "Jack"
fake_user = User(name='Rain', password='12345')
Session.add(fake_user)
print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() )  #这时看session里有你刚添加和修改的数据
Session.rollback() #此时你rollback一下
print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #再查就发现刚才添加的数据没有了。
# Session
# Session.commit()

获取所有数据

print(Session.query(User.name,User.id).all() )

多条件查询

objs = Session.query(User).filter(User.id>0).filter(User.id<7).all()

上面2个filter的关系相当于 user.id >1 AND user.id <7 的效果

统计和分组

Session.query(User).filter(User.name.like("Ra%")).count()

分组

from sqlalchemy import func
print(Session.query(func.count(User.name),User.name).group_by(User.name).all() )

相当于原生sql为

http://www.cnblogs.com/alex3714/articles/5978329.html#

输出为

[(1, ‘Jack’), (2, ‘Rain’)]

外键关联

我们创建一个addresses表,跟user表关联

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String(32), nullable=False)
    user_id = Column(Integer, ForeignKey('user.id'))
    user = relationship("User", backref="addresses") #这个nb,允许你在user表里通过backref字段反向查出所有它在addresses表里的关联项
    def __repr__(self):
        return "<Address(email_address='%s')>" % self.email_address
The relationship.back_populates parameter is a newer version of a very common SQLAlchemy feature calledrelationship.backref. The relationship.backref parameter hasn’t gone anywhere and will always remain available! The relationship.back_populates is the same thing, except a little more verbose and easier to manipulate. For an overview of the entire topic, see the section Linking Relationships with Backref.

表创建好后,我们可以这样反查试试

obj = Session.query(User).first()
for i in obj.addresses: #通过user对象反查关联的addresses记录
    print(i)
addr_obj = Session.query(Address).first()
print(addr_obj.user.name)  #在addr_obj里直接查关联的user表

创建关联对象

obj = Session.query(User).filter(User.name=='rain').all()[0]
print(obj.addresses)
obj.addresses = [Address(email_address="[email protected]"), #添加关联对象
                 Address(email_address="[email protected]")]
Session.commit()

常用查询语法

Common Filter Operators

Here’s a rundown of some of the most common operators used in filter():

  • equals:
     query.filter(User.name == 'ed')
  • not equals:
     query.filter(User.name != 'ed')
  • LIKE:

query.filter(User.name.like(‘%ed%’))

  • IN:
  • NOT IN:
    query.filter(~User.name.in_([‘ed’, ‘wendy’, ‘jack’]))
  • IS NULL:
  • IS NOT NULL:
  • AND:
    2.1. ObjectRelationalTutorial 17
query.filter(User.name.in_(['ed', 'wendy', 'jack']))
# works with query objects too:

query.filter(User.name.in_( session.query(User.name).filter(User.name.like(‘%ed%’))

))

query.filter(User.name == None)
# alternatively, if pep8/linters are a concern
query.filter(User.name.is_(None))
query.filter(User.name != None)
# alternatively, if pep8/linters are a concern
query.filter(User.name.isnot(None))

SQLAlchemy Documentation, Release 1.1.0b1
# use and_()
from sqlalchemy import and_
query.filter(and_(User.name == ‘ed’, User.fullname == ‘Ed Jones’))

# or send multiple expressions to .filter()
query.filter(User.name == 'ed', User.fullname == 'Ed Jones')
# or chain multiple filter()/filter_by() calls
query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')

Note: Makesureyouuseand_()andnotthePythonandoperator! • OR:

Note: Makesureyouuseor_()andnotthePythonoroperator! • MATCH:

query.filter(User.name.match(‘wendy’))
Note: match() uses a database-specific MATCH or CONTAINS f

原文:http://www.cnblogs.com/alex3714/articles/5978329.html

Flask—flask_mail邮箱发送

flask-mail 文档
http://www.pythondoc.com/flask-mail/index.html
项目中不可避免需要使用邮箱认证,如果使用flask则可以利用Flask-Mail来实现

开启qq邮箱SMTP服务

未分类

之后手机验证什么的依自己帐号设置,验证成功后会获得一个授权码,这个需要保存后续发送邮箱时密码就填这个授权码。

安装Flask-Mail

使用 pip 或者 easy_install 安装 Flask-Mail:

pip install Flask-Mail

或者从版本控制系统(github)中下载最新的版本:

git clone https://github.com/mattupstate/flask-mail.git
cd flask-mail
python setup.py install

如果你正在使用 virtualenv,假设你会安装 flask-mail 在运行你的 Flask 应用程序的同一个 virtualenv 上。

配置 Flask-Mail

Flask-Mail 使用标准的 Flask 配置 API 进行配置。下面这些是可用的配置型(每一个将会在文档中进行解释):

MAIL_SERVER : 默认为 ‘localhost’
MAIL_PORT : 默认为 25
MAIL_USE_TLS : 默认为 False
MAIL_USE_SSL : 默认为 False
MAIL_DEBUG : 默认为 app.debug
MAIL_USERNAME : 默认为 None
MAIL_PASSWORD : 默认为 None
MAIL_DEFAULT_SENDER : 默认为 None
MAIL_MAX_EMAILS : 默认为 None
MAIL_SUPPRESS_SEND : 默认为 app.testing
MAIL_ASCII_ATTACHMENTS : 默认为 False
另外,Flask-Mail 使用标准的 Flask 的 TESTING 配置项用于单元测试(下面会具体介绍)。
配置项 默认值 功能
MAIL_SERVER localhost   邮箱服务器
MAIL_PORT   25  端口
MAIL_USE_TLS    False   是否使用TLS
MAIL_USE_SSL    False   是否使用SSL
MAIL_DEBUG  app.debug   是否为DEBUG模式,打印调试消息
MAIL_SUPPRESS_SEND  app.testing 设置是否真的发送邮件,True不发送
MAIL_USERNAME   None    用户名,填邮箱
MAIL_PASSWORD   None    密码,填授权码
MAIL_DEFAULT_SENDER None    默认发送者,填邮箱
MAIL_MAX_EMAILS None    一次连接中的发送邮件的上限
MAIL_ASCII_ATTACHMENTS  False   如果 MAIL_ASCII_ATTACHMENTS 设置成 True 的话,文件名将会转换成 ASCII 的。一般用于添加附件。

大量邮件

通常在一个 Web 应用中每一个请求会同时发送一封或者两封邮件。在某些特定的场景下,有可能会发送数十或者数百封邮件,不过这种发送工作会给交离线任务或者脚本执行。

在这种情况下发送邮件的代码会有些不同:

with mail.connect() as conn:
    for user in users:
        message = '...'
        subject = "hello, %s" % user.name
        msg = Message(recipients=[user.email],
                      body=message,
                      subject=subject)

        conn.send(msg)

与电子邮件服务器的连接会一直保持活动状态直到所有的邮件都已经发送完成后才会关闭(断开)。

有些邮件服务器会限制一次连接中的发送邮件的上限。你可以设置重连前的发送邮件的最大数,通过配置 MAIL_MAX_EMAILS 。

附件

with app.open_resource("image.png") as fp:
    msg.attach("image.png", "image/png", fp.read())

完整例子

from flask import Flask, request
from flask_script import Manager, Shell
from flask_mail import Mail, Message
from threading import Thread


app = Flask(__name__)
app.config['MAIL_DEBUG'] = True             # 开启debug,便于调试看信息
app.config['MAIL_SUPPRESS_SEND'] = False    # 发送邮件,为True则不发送
app.config['MAIL_SERVER'] = 'smtp.qq.com'   # 邮箱服务器
app.config['MAIL_PORT'] = 465               # 端口
app.config['MAIL_USE_SSL'] = True           # 重要,qq邮箱需要使用SSL
app.config['MAIL_USE_TLS'] = False          # 不需要使用TLS
app.config['MAIL_USERNAME'] = '[email protected]'  # 填邮箱
app.config['MAIL_PASSWORD'] = 'Wyf880204*+'      # 填授权码
app.config['MAIL_DEFAULT_SENDER'] = '[email protected]'  # 填邮箱,默认发送者
manager = Manager(app)
mail = Mail(app)


# 异步发送邮件
def send_async_email(app, msg):
    with app.app_context():
        mail.send(msg)


@app.route('/')
def index():
    msg = Message(subject='Hello World',
                  sender="[email protected]",  # 需要使用默认发送者则不用填
                  recipients=['[email protected]'])
    # 邮件内容会以文本和html两种格式呈现,而你能看到哪种格式取决于你的邮件客户端。
    msg.body = 'sended by flask-email'
    msg.html = '<b>测试Flask发送邮件<b>'
    thread = Thread(target=send_async_email, args=[app, msg])
    thread.start()
    return '<h1>邮件发送成功</h1>'


if __name__ == '__main__':
    manager.run()

效果图:

未分类

Python虚拟环境工具Virtualenv的安装与使用

简介

Virtualenv可以为Python提供独立的运行环境,在一定程度上可解决解决依赖、版本以及间接权限等问题。

安装

使用pip命令安装:

$ [sudo] pip install virtualenv  

或使用

$ [sudo] pip install https://github.com/pypa/virtualenv/tarball/master  

安装最新版本。

使用

创建虚拟环境

$ virtualenv venv  

目前版本默认不使用全局Python安装的库,即参数–no-site-packages。如果要继承全局Python的库,则

$ virtualenv --system-site-packages venv  

指定Python的解释器:

$ virtualenv -p /usr/bin/python3.5  venv  

激活虚拟环境

使用前,需要先激活虚拟环境

source venv/bin/activate  

注意此时命令行会多一个(ENV),ENV为虚拟环境名称,接下来所有模块都只会安装到该目录中。

退出虚拟环境

(ENV)$ deactivate  

删除虚拟环境

退出虚拟环境后,在终端输入命令:

(ENV)$ deactivate  
$ rm -r /path/to/ENV  

PS:

Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替virtualenv。

ORM、SQLAlchemy数据库操作

ORM介绍

背景:
用底层的sql写的话,相当于通过pymysql 游标的方式连接“http://blog.51cto.com/jacksoner/2113454 ”,为了避免把sql语句写死在代码里,有没有一种方法直接把原生sql封装好了并且以你熟悉的方式操作,像面向对象那样?

ORM就是对象映射关系程序。相当于ORM帮我们SQL写成类的形式,然后通过类来调用,获取,而不是写底层的sql(insert,update,select)来获取。

ORM 相当于把数据库也给你实例化了,在代码操作mysql中级又加了orm这一层。

orm的优点:
1、隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
2、ORM使我们构造固化数据结构变得简单易行。

sqlalchemy安装

在Python中,最有名的ORM框架是SQLAlchemy。用户包括openstack\Dropbox等知名公司或应用

安装:

pip install SQLAlchemy
SQLAlchemy==1.2.7

pip install pymysql

数据库:

CentOS Linux release 7.4.1708

mysql版本:5.6.35
IP:192.168.1.48
用户:root
密码:123456
创建一个超级用户:grant all privileges on . to jacker@’%’ identified by ‘123456’ WITH GRANT OPTION;
创建一个数据库: mysql> create database sqlalchemy;

方式一:

import pymysql
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String            #创建列,整型,字符串型
engine = create_engine('mysql+pymysql://jacker:[email protected]/sqlalchemy',encoding='utf-8',echo=True)
#echo=True:显示创建sql信息
Base = declarative_base()  # 生成orm基类

#这里的继承Base的类,创建user表,字段id(整型,主键) name(列 字符串32位) 密码(列 字符串64位)
class User(Base):
    __tablename__ = 'user'  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
Base.metadata.create_all(engine) #创建表结构 (这里是父类调子类)

运行结果:

未分类

方式二 创建表,并写入数据:

创建表:

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String

engine = create_engine('mysql+pymysql://jacker:[email protected]/sqlalchemy',encoding='utf-8')
metadata = MetaData(engine)

teacher = Table('user', metadata,
            Column('id', Integer, primary_key=True),
            Column('name', String(50), ),
            Column('fullname', Integer),
            Column('password', String(10)),
)
metadata.create_all(engine)

写入数据:

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('mysql+pymysql://jacker:[email protected]/sqlalchemy',encoding='utf-8')
#echo=True:显示信息
DBsession = sessionmaker(bind=engine)# 实例和engine绑定
session = DBsession()                 # 生成session实例,相当于游标

Base = declarative_base()# 生成orm基类

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String(100))
    fullname = Column(String(100))
    password = Column(String(100))

#实例化操作
user1 = User(id=1001, name='ling', password=123)
user2 = User(id=1002, name='molin', password="123abc")
user3 = User(id=1003, name='karl', password=16)

#需要添加到session中,然后再提交,表里才可以有数据
session.add(user1)
session.add(user2)
session.add(user3)
session.commit()

验证:

未分类

数据查询

my_user=session.query(User).filter_by(name='molin').first()#显示匹配name=molin的第一条数据,因为name='molin' 可能有多个值
my = session.query(User).filter_by().all()                  #显示所有
print(my)                                                   #这个是个列表,通过循环遍历
for i in my:
    print(i.name)
    print(i.password)
print(my_user.id,my_user.password,my_user.name)             #调用
#session.commit()                                          #查询就不用提交了
session.close()
'''
filter和filter_by   条件查询

filter_by(name="ling")  不能使用>  <  =
filter(Student.id>1001)  这个就必须使用Student.id  可以使用> < =等
'''
a = session.query(User).filter(User.id>1002).all()
for i in a:
    print(i.name)
    print(i.password)
session.close()
如果出现name相同的,想都打印出来的话:
#实例化操作
user1 = User(id=1001, name='test1', password=123)
user2 = User(id=1002, name='test2', password="123abc")
user4 = User(id=1004, name='test2', password="123abc")
user3 = User(id=1003, name='test3', password=16)

my_user = session.query(User).filter_by(name="test2").all()       #my_user:这个是列表
for i in my_user:
    print(i.id)
    print(i.name)
    print(i.password)
多条件查询

objs = Session.query(User).filter(User.id>0).filter(User.id<7).all()

上面2个filter的关系相当于 user.id >1 AND user.id <7 的效果

修改数据

my_user = session.query(User).filter_by(name="molin").first()
my_user.name = "fenggf" # 查询出来之后直接赋值修改
my_user.passwork = "123qwe"
session.commit()

bootstrap flask登录页面编写实例

本文章来为各位介绍一个python的例子,这个就是bootstrap+flask写登录页面的例子,希望文章能够对各位有所帮助。
Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。在一般应用或个人开发中,可以很容易的写出应用。本篇就结合bootstrap,写一个简单的login界面。

一、效果图

无图无真像,先上效果图:

未分类

flask-login

未分类

二、目录结构

该代码写时采用动静分离的方法进行编写,目录树如下:

[root@jb51 login]# tree
.
├── run.py
├── static
│   └── css
│       ├── bootstrap.min.css
│       └── style.css
└── templates
    ├── index.html
    └── login.html

三、入口run文件

动态代码只有一个run.py文件,代码如下:

from flask import *
app = Flask(__name__,static_url_path='/static')
@app.route("/login",methods=['POST','GET'])
def login():
 error = None
 if request.method == 'POST':
 if request.form['username'] != 'admin' or request.form['password'] != 'admin123':
  error= "sorry"
 else:
  return redirect(url_for('index'))
 return render_template('login.html',error=error)
@app.route("/index")
def index():
 return render_template('index.html')
if __name__ == "__main__":
 app.run(
 host="0.0.0.0",
 port=80,
 debug=True)

实际应用中,根据需要,可以关闭debug模试。

四、静态模块

templates下有两个模块文件分别是login.html和index.html
login.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1.0" />
<title>Bootstrap响应式登录界面模板</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div class="box">
<div class="login-box">
<div class="login-title text-center">
<h1><small>登录</small></h1>
</div>
<div class="login-content ">
<div class="form">
<form action="#" method="post">
<div class="form-group">
 <div class="col-xs-12 ">
  <div class="input-group">
   <span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
   <input type="text" id="username" name="username" class="form-control" placeholder="用户名">
  </div>
 </div>
</div>
<div class="form-group">
 <div class="col-xs-12 ">
  <div class="input-group">
   <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
   <input type="text" id="password" name="password" class="form-control" placeholder="密码">
  </div>
 </div>
</div>
<div class="form-group form-actions">
 <div class="col-xs-4 col-xs-offset-4 ">
  <button type="submit" class="btn btn-sm btn-info"><span class="glyphicon glyphicon-off"></span> 登录</button>
 </div>
</div>
<div class="form-group">
 <div class="col-xs-6 link">
  <p class="text-center remove-margin"><small>忘记密码?</small> <a href="javascript:void(0)" ><small>找回</small></a>
  </p>
 </div>
 <div class="col-xs-6 link">
  <p class="text-center remove-margin"><small>还没注册?</small> <a href="javascript:void(0)" ><small>注册</small></a>
  </p>
 </div>
</div>
</form>
</div>
</div>
</div>
</div>
<div ><p>来源:<a href="http://www.jb51.net/" target="_blank">运维之路</a></p></div>
</body>
</html>

index.html
index.html 模板中内容如下:

<h1>welcome to www.jb51.net/ <h1>

如果大家还想深入学习,可以点击这里进行学习,再为大家附两个精彩的专题:Bootstrap学习教程 Bootstrap实战教程
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持51dev开发社区。
以上就是bootstrap flask登录页面编写实例的全部内容,希望对大家的it技术学习有所帮助,希望大家多多支持技术开发者社区。

Django+Ngnix+Gunicorn+Mysql部署Centos的坑

环境配置

  • Centos 7
  • Python 3.6.5
  • Virtualenvwrapper 4.8.2
  • Django 2.0.5
  • Mysql 5.7.22
  • Ngnix 1.12.2
  • Gunicorn 19.8.1

注:这并不是什么教程

python虚拟环境配置

Virtualenvwrapper安装失败

试试这条命令 :-p

sudo pip install virtualenvwrapper --upgrade --ignore-installed six

简答解释就是包six版本有点低,详细解释点此

找不到virtualenvwrapper.sh文件

按照官方文档上说是安在 /usr/local/bin/virtualenvwrapper.sh,但是并没有,每个系统的情况不一样,使用如下命令

pip uninstall virtualenvwrapper

不用担心,这并不会立刻移除virtualenvwrapper,会输出以下内容,再输入n取消安装

Uninstalling virtualenvwrapper-4.8.2:
  /usr/bin/virtualenvwrapper.sh
  /usr/bin/virtualenvwrapper_lazy.sh
  /usr/lib/python2.7/site-packages/virtualenvwrapper-4.8.2-py2.7-nspkg.pth
  /usr/lib/python2.7/site-packages/virtualenvwrapper-4.8.2.dist-info/DESCRIPTION.rst
  /usr/lib/python2.7/site-packages/virtualenvwrapper-4.8.2.dist-info/INSTALLER
  /usr/lib/python2.7/site-packages/virtualenvwrapper-4.8.2.dist-info/METADATA
  ......
  Proceed (y/n)?

看第一行,这下知道在哪里的吧,对于我的centos7来说是在 /usr/bin/virtualenvwrapper.sh 下

具体见此https://stackoverflow.com/questions/12647266/where-is-virtualenvwrapper-sh-after-pip-install/41676706#41676706

Mysql配置

安装教程https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-centos-7 ,比较靠谱

中文乱码

问题可能出现在两个地方,一个是Django的配置文件中,还有一个就是Mysql的配置出问题

Django数据配置

找到project的settings.py,修改这两个地方,注意,对于较新版本的django,把zh-cn改成了zh-Hans

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

Mysql数据配置

先登录到你的mysql中,执行如下命令

SHOW VARIABLES LIKE 'character_set_%';

发现大多数行的值都不是utf-8,而是latin1

那么,找到mysql的配置文件my.cnf

对于 MySQL 5.7+,执行以下命令,别的情况见此

mysqladmin --help | grep 'Default options' -A 2

输出的第二行就是文件的所在

Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

打开此文件 /etc/my.cnf

添加如下内容如下,别的地方别修改

[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8

...

[mysql]
default-character-set=utf8

改完之后记得重启mysql服务

sudo systemctl restart mysqld

gunicorn找不到 django.core.xxx

找到gunicorn的所在地

which gunicorn

应为是在python虚拟环境下安装的,所以一般在//.virtualenvs//bin/gunicorn,如果不是这样的话终极解决方案是把要输入 gunicorn 的地方全改成 //.virtualenvs//bin/gunicorn

Django 静态文件404

在production模式下Django并不支持静态文件的处理,这一切都要交给一个服务器处理,比如此处的Nginx,千万要记住!!!!!!

Nginx无法正常启动

(ps1:centos7安装Nginx的教程见此,比较靠谱)

(ps2:默认相关防火墙已开启)

在输入

sudo systemctl start nginx
sudo systemctl status nginx

发现其启动失败,则多半是你配置文件写错的结果,输入一下命令排错

sudo nginx -t

修改完之后记得刷新哦

sudo service nginx restart
#或者
sudo service nginx reload

linux系统中编译安装postgresql

以postgresql-9.6.2为例

# wget https://ftp.postgresql.org/pub/source/v9.6.2/postgresql-9.6.2.tar.gz
# tar zxvf postgresql-9.6.2.tar.gz
# cd postgresql-9.6.2
# ./configure --prefix=/usr/local/postgresql
# make 
# make install

给postgresql添加用户 (因为创建database cluster时不能用root帐号)

# useradd postgres 
# passwd postgres

建立database cluster目标文件夹

# mkdir -p /mnt/data/pgsql 
# chown -R postgres /mnt/data/pgsql

环境变量设置

# su - postgres  //切换到postgres用户
$ vi .bash_profile

在末尾添加如下内容

# postgres 
PGDATA=/mnt/data/pgsql 
PATH=/usr/local/pgsql/bin:$PATH 
export PGDATA PATH

使环境变量生效

$ source .bash_profile

初始化数据库

pg_ctl initdb

启动数据库实例

$pg_ctl -D /mnt/data/pgsql -l logfile start //设置好PGDATA环境变量后,可以不带-D选项

关闭数据库实例

$ pg_ctl stop