flask-sqlalchemy 简单笔记

字数 阅读 评论 喜欢

flask-sqlalchemy

SQLAlchemy已经成为了python世界里面orm的标准,flask是一个轻巧的web框架,可以自由的使用orm,其中flask-sqlalchemy是专门为flask指定的插件。

安装flask-sqlalchemy

pip install flask-sqlalchemy

初始化sqlalchemy

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy app = Flask(__name__) # dialect+driver://username:password@host:port/database?charset=utf8
# 配置 sqlalchemy 数据库驱动://数据库用户名:密码@主机地址:端口/数据库?编码
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@localhost:3306/sqlalchemy?charset=utf8'
# 初始化
db = SQLAlchemy(app)

定义model

class User(db.Model):
""" 定义了三个字段, 数据库表名为model名小写
"""
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True) def __init__(self, username, email):
self.username = username
self.email = email def __repr__(self):
return '<User %r>' % self.username def save(self):
db.session.add(self)
db.session.commit()

创建数据表

数据包的创建使用sqlalchemy app,如果表已经存在,则忽略,如果不存在,则新建

>>> from yourapp import db, User
>>> u = User(username='admin', email='admin@example.com') # 创建实例
>>> db.session.add(u) # 添加session
>>> db.session.commit() # 提交查询
>>> users = User.query.all() # 查询

需要注意的是,如果要插入中文,必须插入 unicode字符串

>>> u = User(username=u'人世间', email='rsj@example.com')
>>> u.save()

定义关系

关系型数据库,最重要的就是关系。通常关系分为 一对一(例如无限级栏目),一对多(文章和栏目),多对多(文章和标签)

one to many

我们定义一个Category(栏目)和Post(文章),两者是一对多的关系,一个栏目有许多文章,一个文章属于一个栏目。

class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50)) def __init__(self, name):
self.name = name def __repr__(self):
return '<Category %r>' % self.name class Post(db.Model):
""" 定义了五个字段,分别是 id,title,body,pub_date,category_id
"""
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
pub_date = db.Column(db.String(20))
# 用于外键的字段
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
# 外键对象,不会生成数据库实际字段
# backref指反向引用,也就是外键Category通过backref(post_set)查询Post
category = db.relationship('Category', backref=db.backref('post_set', lazy='dynamic')) def __init__(self, title, body, category, pub_date=None):
self.title = title
self.body = body
if pub_date is None:
pub_date = time.time()
self.pub_date = pub_date
self.category = category def __repr__(self):
return '<Post %r>' % self.title def save(self):
db.session.add(self)
db.session.commit()

如何使用查询呢?

>>> c = Category(name='Python')
>>> c
<Category 'Python'>
>>> c.post_set
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B58F60>
>>> c.post_set.all()
[]
>>> p = Post(title='hello python', body='python is cool', category=c)
>>> p.save()
>>> c.post_set
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B73710>
>>> c.post_set.all() # 反向查询
[<Post u'hello python'>]
>>> p
<Post u'hello python'>
>>> p.category
<Category u'Python'>
# 也可以使用category_id 字段来添加
>>> p = Post(title='hello flask', body='flask is cool', category_id=1)
>>> p.save()

many to many

对于多对多的关系,往往是定义一个两个modelid的另外一张表,例如 Post 和 Tag之间是多对多,需要定义一个 Post_Tag的表

post_tag = db.Table('post_tag',
db.Column('post_id', db.Integer, db.ForeignKey('post.id')),
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'))
) class Post(db.Model): id = db.Column(db.Integer, primary_key=True)
# ... 省略
# 定义一个反向引用,tag可以通过 post_set查询到 post的集合
tags = db.relationship('Tag', secondary=post_tag,
backref=db.backref('post_set', lazy='dynamic')) class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(10), unique=True)
# 定义反向查询
posts = db.relationship('Post', secondary=post_tag,
backref=db.backref('tag_set', lazy='dynamic')) def __init__(self, content):
self.content = content def save(self):
db.session.add(self)
db.session.commit()

查询

>>> tag_list = []
>>> tags = ['python', 'flask', 'ruby', 'rails']
>>> for tag in tags:
t = Tag(tag)
tag_list.append(t)
>>> tag_list
[<f_sqlalchemy.Tag object at 0x0000000003B7CF28>, <f_sqlalchemy.Tag object at 0x0000000003B7CF98>, <f_sqlalchemy.Tag object at 0x0000000003B7CEB8>, <f_sqlalchemy.Tag object at 0x0000000003B7CE80>]
>>> p
<Post u'hello python'>
>>> p.tags
[]
>>> p.tags = tag_list # 添加多对多的数据
>>> p.save()
>>> p.tags
[<f_sqlalchemy.Tag object at 0x0000000003B7CF28>, <f_sqlalchemy.Tag object at 0x0000000003B7CF98>, <f_sqlalchemy.Tag object at 0x0000000003B7CEB8>, <f_sqlalchemy.Tag object at 0x0000000003B7CE80>]
>>> p.tag_set # 反向查询
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B7C080>
>>> p.tag_set.all()
[<f_sqlalchemy.Tag object at 0x0000000003B7CF28>, <f_sqlalchemy.Tag object at 0x0000000003B7CF98>, <f_sqlalchemy.Tag object at 0x0000000003B7CEB8>, <f_sqlalchemy.Tag object at 0x0000000003B7CE80>]
>>> t = Tag.query.all()[1]
>>> t
<f_sqlalchemy.Tag object at 0x0000000003B7CF28>
>>> t.content
u'python'
>>> t.posts
[<Post u'hello python'>]
>>> t.post_set
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B7C358>
>>> t.post_set.all()
[<Post u'hello python'>]

self one to one

自身一对一也是常用的需求,比如无限分级栏目

class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
# 父级 id
pid = db.Column(db.Integer, db.ForeignKey('category.id'))
# 父栏目对象
pcategory = db.relationship('Category', uselist=False, remote_side=[id], backref=db.backref('scategory', uselist=False)) def __init__(self, name, pcategory=None):
self.name = name
self.pcategory = pcategory def __repr__(self):
return '<Category %r>' % self.name def save(self):
db.session.add(self)
db.session.commit()

查询

>>> p = Category('Python')
>>> p
<Category 'Python'>
>>> p.pid
>>> p.pcategory # 查询父栏目
>>> p.scategory # 查询子栏目
>>> f = Category('Flask', p)
>>> f.save()
>>> f
<Category u'Flask'>
>>> f.pid
1L
>>> f.pcategory # 查询父栏目
<Category u'Python'>
>>> f.scategory # 查询父栏目
>>> p.scategory # 查询子栏目
<Category u'Flask'>

关于 flask-sqlalchemy 定义models的简单应用就这么多,更多的技巧在于如何查询。

Python学习笔记2-flask-sqlalchemy 简单笔记的更多相关文章

  1. SQLAlchemy 简单笔记

    ORM 江湖##### 曾几何时,程序员因为惧怕SQL而在开发的时候小心翼翼的写着sql,心中总是少不了恐慌,万一不小心sql语句出错,搞坏了数据库怎么办?又或者为了获取一些数据,什么内外左右连接,函 ...

  2. python学习之路-第六天-一个简单的脚本

    现在有一个需求:把某个目录下的文件备份到指定到另外一个目录下,而且压缩后文件为zip文件 # -*- coding:utf-8 -*- #! /usr/bin/python # Filename:ba ...

  3. Python学习---range/for/break/continue简单使用

    range的使用:注意,在python3中,交互模式下已经不显示了 for循环的使用 打印50-70 # 第一种方案 for i in range(100): if i <= 70 and i ...

  4. Python学习笔记(二)网络编程的简单示例

    Python中的网络编程比C语言中要简洁很多,毕竟封装了大量的细节. 所以这里不再介绍网络编程的基本知识.而且我认为,从Python学习网络编程不是一个明智的选择.   简单的TCP连接 服务器代码如 ...

  5. python简介以及简单代码——python学习笔记(一)

    学习来源:https://www.liaoxuefeng.com/wiki/1016959663602400 了解python 简单编写并实现python代码 命令行模式和python交互模式 了解p ...

  6. python学习笔记十三:Flask demo

    一.Flask简介 Flask 是一个 Python 实现的 Web 开发微框架.官网:http://flask.pocoo.org/ 二.Demo 1.代码结构 . ├── blog.py ├── ...

  7. Python学习笔记整理总结【ORM(SQLAlchemy)】

    一.介绍SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执 ...

  8. python学习笔记目录

    人生苦短,我学python学习笔记目录: week1 python入门week2 python基础week3 python进阶week4 python模块week5 python高阶week6 数据结 ...

  9. Python学习笔记—Python基础1 介绍、发展史、安装、基本语法

    第一周学习笔记: 一.Python介绍      1.Python的创始人为吉多·范罗苏姆.1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...

随机推荐

  1. noip 2010 关押罪犯 (二分图染色 并茶几)

    /* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色 ...

  2. JavaScript—window对象使用

    window对象是JavaScript浏览器对象模型中的顶层对象,包含多个常用方法和属性: 1. 打开新窗口 window.open(pageURL,name,parameters) 其中:pageU ...

  3. JavaScript--对象+函数

    1. 复杂数据类型 Object ECMAScript中的对象其实就是一组数据(属性)和功能(方法)的集合.    1) 创建Object实例:   1.使用构造函数创建,new Object()   ...

  4. 【Usaco2008 Mar】土地购买

    [题目描述] 农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <= 1,000,000; ...

  5. jquery find选择器在不同浏览器下的差异

    初步测试,5000个节点的隐藏. 代码如下: <!doctype html> <html lang="en"> <head> <scrip ...

  6. int, NSInteger, NSUInteger, NSNumber的区别

    新手在接触iOS或者Mac开发的时候,看到int和NSInteger,一般不清楚应该用哪个比较合适.我们先来查看下NSInteger的定义 #if __LP64__ || (TARGET_OS_EMB ...

  7. Configuration ReportNG with TestNG

    下载 Reporter.jar,velocity-dep-1.4.jar 和 Guice.jar: 配置项目属性:Properties ->TestNG ->Disable Default ...

  8. javascript 中的nextSibling和previousSibling使用注意事项

    JavaScript中的nextSibling和previousSibling和作用类似于jquery的next()和prev(),都是获取下一个/上一个同胞元素,如果下一个同级节点不存在,则此属性返 ...

  9. c# sqlserver备份还原(转)

    WinForm c# 备份 还原 数据库 其实是个非常简单的问题,一个Form,一个Button,一个OpenFileDialog,一个SaveFileDialog.下面给出备份与还原类 using ...

  10. Python学习笔记:02数据类型

    Python 数据类型 python中标准的数据类型有 基础类型 整型(长整型) 浮点型 复数型 布尔型 序列类型 字符串 列表 元组 字典 整型 整型和长整型并不严格区分,整型int的表达范围和计算 ...