Django/MySql数据库基本操作&ORM操作
数据库配置:
#第一步在settings里面 DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': 'xx',
'PORT': 6666,
}
} #第二步
# 如下设置放置的与project同名的配置的 __init__.py文件中
import pymysql
pymysql.install_as_MySQLdb()
数据库基本操作
conn = pymysql.connect(host='localhost', port=3307, user='root', passwd='88888', db='learing',charset='utf8')
# 创建连接 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 创建游标 cursor.execute("select id,title from class")
#执行SQL语句
#cursor.fetchone() #是个字典
#conn.commit() 增、删、改
class_list=cursor.fetchall()
cursor.close()
conn.close() #--------大量重复后可以将其功能写成一个类 class SqlHelper(): # def __init__(self):
# self.connect()
#也可以把那个链接的内容写成配置文件(活的)
#只要一建立对象,就直接链接上 def connect(self):
self.conn=pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='94188', db='exercise',charset='utf8')
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) def get_list(self,sql,args):
self.cursor.execute(sql,args)
result=self.cursor.fetchall()
return(result) def get_one(self,sql,args):
self.cursor.execute(sql,args)
result = self.cursor.fetchone()
return (result) def modify(self,sql,args):
self.cursor.execute(sql,args)
self.conn.commit() def multiple_modify(self,sql,args):
#self.cursor.executemany('insert into ba(id,name)'value(%s,%s),[(1,'abv'),(2,'ffff')])
self.cursor.executemany(sql,args)
self.conn.commit() def add_create(self,sql,args):
self.cursor.execute(sql,args)
self.conn.commit()
return self.cursor.lastrowid #获取最后的一个id并且返回 def close(self):
self.cursor.close()
# 关闭连接
self.conn.close() #后面使用建立个类的对象,调用其方法就行
obj = SqlHelper()
obj.connect()
obj.get_list()
...
obj.close()
ORM操作
ORM利用pymysql等第三方工具连接数据库
Django默认连接SQLlite(文件型数据库db.sqlite3)
所以要把setting里面修改为
DATABASES = { 'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'Kant',
} }
#这个数据库要事先创建好
默认用的是mysql-->MySQLDB(下面方法修改Django默认连接方式)
# 如下设置放置的与project同名的配置的 __init__.py文件中 import pymysql
pymysql.install_as_MySQLdb()
在目录app01--models.py里面 写上对应的类,然后生成表
class UserGroup(models.Model):
title=models.CharField(max_length=32)
#生成的表会自动带id属性, #然后顺序执行下面个代码(每次修改表都要顺序执行一遍)
#python manage.py makemigrations
#python manage.py migrate
基本操作语句
models.UserInfo.objects.create(user='程颢',password=12306,age=365,ug_id=1)
#增加 models.UserGroup.objects.filter(id=2).delete()
#删除 models.UserGroup.objects.filter(id=1).update(title='明道先生')
#修改 models.UserGroup.objects.filter(id=2).first()
resdult=models.UserInfo.objects.all()
models.Tb1.objects.get(id=123) #获取单条数据,不存在则报错,不推荐
#查找
补充语句(.values() & .all() & .filter(**condition) )
resdult=models.UserInfo.objects.all().values('user','age') # 字典类型python
for row in resdult:
print(row,row['user']) #从完整表找出其'user','age',以之为key构造关于其对应内容的字典
#格式为:{'user': '程颐', 'age': 18, } resdult=models.UserInfo.objects.all()
#<QuerySet [<UserInfo: 1-程颐>, <UserInfo: 2-王阳明>]>
#拿到表全部数据,形式类似列表,可通过循环或者.values获取相关分量 resdult=models.UserInfo.objects.all().first
#取出第一个对象,相当于一行(一个元组)
#可以通过(.属性名)来获取相关分量
condition={'xx':'xx','yy':'yy'}
models.UserGroup.objects.filter(**condition)
#还可以传字典,查询的时候是and的关系
进阶操作(神奇双下划线__进行数据库操作)
# 获取个数
#
# models.Tb1.objects.filter(name='seven').count() # 大于,小于
#
# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
# models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 # in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # isnull
# Entry.objects.filter(pub_date__isnull=True) # contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
# models.Tb1.objects.exclude(name__icontains="ven") # range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # 其他类似
#
# startswith,istartswith, endswith, iendswith, # order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc # group by
#
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" # limit 、offset
#
# models.Tb1.objects.all()[10:20] # regex正则匹配,iregex 不区分大小写
#
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +') # date
#
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1)) # year
#
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005) # month
#
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6) # day
#
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3) # week_day
#
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2) # hour
#
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12) # minute
#
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29) # second
#
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31) 进阶操作
F、Q、extra
###F可把表里面同一属性集体增减,比如全部人工资增加1000
from django.db.models import F
models.Tb1.objects.update(salary=F('salary')+1000) ###Q可以多复杂条件同时查询(同时存在and & or)
from django.db.models import Q #Q是写在.filter()里面 方法一: Q(id=10)
Q(id=8) | Q(id=10) #or
Q(id=8) & Q(id=10) #and
Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
models.UserInfo.objects.filter(Q(nid=1) | Q(nid=3) ).all().values('user','age',).first()['user'] 方法二: # q1 = Q()
# q1.connector = 'OR'
# q1.children.append(('id', 1))
# q1.children.append(('id', 10))
# q1.children.append(('id', 9))
#q1内部加这么多条件通过OR连接 # q2 = Q()
# q2.connector = 'OR'
# q2.children.append(('c1', 1))
# q2.children.append(('c1', 10))
# q2.children.append(('c1', 9))
#q2内部加这么多条件通过OR连接 con = Q()
con.add(q1, 'AND')
con.add(q2, 'AND')
#con内部加这么多条件通过AND连接
#以便应对组合查询 #可以写个字典,动态生成这个查询 #models.Tb1.objects.filter(con) ###extra,额外的
# extra(self, select=None,select_params=None, where=None, params=None, tables=None, order_by=None, )
# Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
# Entry.objects.extra(where=['headline=%s'], params=['Lennon']) #where跟 params匹配用
# Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"]) #列表元素跟元素之间通过and连接,元素内部可以用or连接
# Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
# Entry.objects.extra(tables=['app01_usertype'],where=[])
#相当于select * from Entry,app01_usertype #笛卡尔积 v=models.UserInfo.objects.all().extra(select={'n':'select count(1) from app01_UserGroup where id>%s and id<%s' },select_params=[1,4])
for i in v:
print(i.user,i.n)
#占位符号多的话可以挨个加, 往后面加就行
#这个i.n为新的字段(列)会加到查询的表中 extra
#可以全部用上
models.UserInfo.objects.extra ( select={ 'newid' : 'select count(1) from app01_ usertype where id>&s'},
select_ params=[1,] , where =['age>%s'] ,
params= [18,], order_by=['-age'],
tables= ['app01_ usertype'] )
相当于:
select
app01_userinfo.id,
(select count(1) from app01_usertype where id>1) as newid
from app01_userinfo, app01_ usertype
where
app01_ userinfo.age > 18
order by
app01_ userinfo.age desc # 执行原生SQL
# from django.db import connection, connections
# cursor = connection.cursor() #默认的数据库
# cursor = connections['default'].cursor() #指定的数据库 settings里面可以DATABASES可以有多个数据库
# cursor.execute("""SELECT * from auth_user where id = %s""", [1])
# row = cursor.fetchone()
# row = cursor.fetchall()
models. xxx.objects.** . **可以是一些操作(多)
##################################################################
# PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
################################################################## def all(self)
# 获取所有的数据对象 def filter(self, *args, **kwargs)
# 条件查询
# 条件可以是:参数,字典,Q def exclude(self, *args, **kwargs)
# 条件查询
# 条件可以是:参数,字典,Q def select_related(self, *fields)
性能相关:表之间进行join连表操作,一次性获取关联的数据。
model.tb.objects.all().select_related()
model.tb.objects.all().select_related('外键字段')
model.tb.objects.all().select_related('外键字段__外键字段') def prefetch_related(self, *lookups)
性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
# 获取所有用户表
# 获取用户类型表where id in (用户表中的查到的所有用户ID)
models.UserInfo.objects.prefetch_related('外键字段') from django.db.models import Count, Case, When, IntegerField
Article.objects.annotate(
numviews=Count(Case(
When(readership__what_time__lt=treshold, then=1),
output_field=CharField(),
))
) students = Student.objects.all().annotate(num_excused_absences=models.Sum(
models.Case(
models.When(absence__type='Excused', then=1),
default=0,
output_field=models.IntegerField()
))) def annotate(self, *args, **kwargs)
# 用于实现聚合group by查询 from django.db.models import Count, Avg, Max, Min, Sum v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
# SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
# SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
# SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 def distinct(self, *field_names)
# 用于distinct去重
models.UserInfo.objects.values('nid').distinct()
# select distinct nid from userinfo 注:只有在PostgreSQL中才能使用distinct进行去重 def order_by(self, *field_names)
# 用于排序
models.UserInfo.objects.all().order_by('-id','age') def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
# 构造额外的查询条件或者映射,如:子查询 Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid']) def reverse(self):
# 倒序
models.UserInfo.objects.all().order_by('-nid').reverse()
# 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序 def defer(self, *fields):
models.UserInfo.objects.defer('username','id')
或
models.UserInfo.objects.filter(...).defer('username','id')
#映射中排除某列数据 def only(self, *fields):
#仅取某个表中的数据
models.UserInfo.objects.only('username','id')
或
models.UserInfo.objects.filter(...).only('username','id') def using(self, alias):
指定使用的数据库,参数为别名(setting中的设置) ##################################################
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
################################################## def raw(self, raw_query, params=None, translations=None, using=None):
# 执行原生SQL
models.UserInfo.objects.raw('select * from userinfo') # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
models.UserInfo.objects.raw('select id as nid from 其他表') # 为原生SQL设置参数
models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,]) # 将获取的到列名转换为指定列名
name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
Person.objects.raw('SELECT * FROM some_other_table', translations=name_map) # 指定数据库
models.UserInfo.objects.raw('select * from userinfo', using="default") ################### 原生SQL ###################
from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone() # fetchall()/fetchmany(..) def values(self, *fields):
# 获取每行数据为字典格式 def values_list(self, *fields, **kwargs):
# 获取每行数据为元祖 def dates(self, field_name, kind, order='ASC'):
# 根据时间进行某一部分进行去重查找并截取指定内容
# kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
# order只能是:"ASC" "DESC"
# 并获取转换后的时间
- year : 年-01-01
- month: 年-月-01
- day : 年-月-日 models.DatePlus.objects.dates('ctime','day','DESC') def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
# 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
# kind只能是 "year", "month", "day", "hour", "minute", "second"
# order只能是:"ASC" "DESC"
# tzinfo时区对象
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai')) """
pip3 install pytz
import pytz
pytz.all_timezones
pytz.timezone(‘Asia/Shanghai’)
""" def none(self):
# 空QuerySet对象 ####################################
# METHODS THAT DO DATABASE QUERIES #
#################################### def aggregate(self, *args, **kwargs):
# 聚合函数,获取字典类型聚合结果
from django.db.models import Count, Avg, Max, Min, Sum
result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
===> {'k': 3, 'n': 4} def count(self):
# 获取个数 def get(self, *args, **kwargs):
# 获取单个对象 def create(self, **kwargs):
# 创建对象 def bulk_create(self, objs, batch_size=None):
# 批量插入
# batch_size表示一次插入的个数
objs = [
models.DDD(name='r11'),
models.DDD(name='r22')
]
models.DDD.objects.bulk_create(objs, 10) def get_or_create(self, defaults=None, **kwargs):
# 如果存在,则获取,否则,创建
# defaults 指定创建时,其他字段的值
obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2}) def update_or_create(self, defaults=None, **kwargs):
# 如果存在,则更新,否则,创建
# defaults 指定创建时或更新时的其他字段
obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1}) def first(self):
# 获取第一个 def last(self):
# 获取最后一个 def in_bulk(self, id_list=None):
# 根据主键ID进行查找
id_list = [11,21,31]
models.DDD.objects.in_bulk(id_list) def delete(self):
# 删除 def update(self, **kwargs):
# 更新 def exists(self):
# 是否有结果 其他操作
连表操作(了不起的双下划线、反查)
性能优化
resdult=models.UserInfo.objects.all()
for row in resdult:
print(row.name,row.ut.title) #row.ut.title是通过外键ut跨表后查询另外表中对应的titile属性
#存在问题:这样要执行很多次数据库操作,比较耗资源
#改进1.查询一次,生成个字典,然后通过索引取值
resdult=models.UserInfo.objects.all().values('user','age','password') #.values字典类型 每一个元素都是一个字典(包含一行数据)
for row in resdult:
print(row,row['user']) #通过索引取值 #改进2.select_related主动做连表查询一次 (数据量小的时候可以用) resdult=models.UserInfo.objects.all().select_related('ut','gp',...) #直接与外键('ut','gp')连接的表(可以多个)连接起来 [一次就好]
for row in resdult: #row是对象
print(row.name,row.ut.title) # 这样就不同发额外sql请求 #与下面的prefetch_related比较:
#优点:节省硬盘空间
#缺点:连表性能差(用户量大的时候) #改进3:prefetch_related不做连表,做两次查询
#一次查询UserInfo整合结果集(去重),再根据已知条件查一次ut外键相关的那个表,然后两者结果合一。(数据量大的时候用) resdult=models.UserInfo.objects.all().prefetch_related('ut')
for row in resdult: #row是对象
print(row.name,row.ut.title) # 这样就不同发额外sql请求
Django/MySql数据库基本操作&ORM操作的更多相关文章
- Django中的app及mysql数据库篇(ORM操作)
Django常见命令 在Django的使用过程中需要使用命令让Django进行一些操作,例如创建Django项目.启动Django程序.创建新的APP.数据库迁移等. 创建Django项目 一把我们都 ...
- python【第十二篇下】操作MySQL数据库以及ORM之 sqlalchemy
内容一览: 1.Python操作MySQL数据库 2.ORM sqlalchemy学习 1.Python操作MySQL数据库 2. ORM sqlachemy 2.1 ORM简介 对象关系映射(英语: ...
- python操作mysql数据库的相关操作实例
python操作mysql数据库的相关操作实例 # -*- coding: utf-8 -*- #python operate mysql database import MySQLdb #数据库名称 ...
- linux系统上Mysql数据库导入导出操作
需求:把MySQL数据库目录中的dz数据库备份到/home/dz_bak.sql ,然后再新建一个数据库dzbak,最后把/home/dz_bak.sql 导入到数据库dzbak中.操作如下:以下操作 ...
- 【代码学习】MYSQL数据库的常见操作
---恢复内容开始--- ============================== MYSQL数据库的常见操作 ============================== 一.mysql的连接与 ...
- PHP对MySQL数据库的相关操作
一.Apache服务器的安装 <1>安装版(计算机相关专业所用软件---百度云链接下载)-直接install<2>非安装版(https://www.apachehaus.com ...
- mysql 数据库必备命令操作,入门练习一下
mysql 数据库必备命令操作 show databases: 查看所有的数据库: create database jfedu: 创建名为jfedu数据库: use nihao: 进入jfedu数据库 ...
- 第二百七十九节,MySQL数据库-pymysql模块操作数据库
MySQL数据库-pymysql模块操作数据库 pymysql模块是python操作数据库的一个模块 connect()创建数据库链接,参数是连接数据库需要的连接参数使用方式: 模块名称.connec ...
- 第二百七十八节,MySQL数据库-表内容操作
MySQL数据库-表内容操作 1.表内容增加 insert into 表 (列名,列名...) values (值,值,值...); 添加表内容添加一条数据 insert into 表 (列名,列名. ...
随机推荐
- Linux 下命令有哪几种可使用的通配符?分别代表什么含义?
"?"可替代单个字符. "*"可替代任意多个字符. 方括号"[charset]"可替代 charset 集中的任何单个字符,如[a-z],[ ...
- ruoyi首次使用常见问题的解决方案
1.导入项目之后,下载依赖包之后,模块的依赖项飘红(我这里无法复现,当参考图吧) 解决方法: 2.ruoyi框架代码生成之后,需要自己进行替换到指定位置.相应的官方文档位置,否则,可能会出现404,访 ...
- 阐述 final、finally、finalize 的区别?
final:修饰符(关键字)有三种用法:如果一个类被声明为 final,意味 着它不能再派生出新的子类,即不能被继承,因此它和 abstract 是反义词.将 变量声明为 final,可以保证它们在使 ...
- SSM-learning
架构流程图: 第一步:建立spring框架: 包括:建立所需要的dao层,sevice层和controller层和实体类,建立spring配置文件,配置自动扫描bean AccountDao: @Re ...
- 你对 Spring Boot 有什么了解?
事实上,随着新功能的增加,弹簧变得越来越复杂.如果必须启动新的 spring 项 目,则必须添加构建路径或添加 maven 依赖项,配置应用程序服务器,添加 spring 配置.所以一切都必须从头开始 ...
- 用maven建立一个工程4
在命令行里面输入cd C:\Users\admin\Documents\hello 然后按回车 再输入这行代码 mvn archetype:generate -DgroupId=com.liyongz ...
- 机器学习之近邻算法模型(KNN)
1..导引 如何进行电影分类 众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪 个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问 ...
- ElasticSearch-学习笔记01-docker安装
安装ElasticSearch docker 安装请参考: https://www.cnblogs.com/youxiu326/p/docker-01.html docker run -d --nam ...
- 运筹学之"连通图"和"最小枝杈树"和"最短路线问题"
一.连通图 必须每个点都有关系 图1 不算连通图 图2含有圈v1,v2,v5,可优化 图3就是所需的连通图 注意:图>连通图>树 二.最小枝杈树 获取是所有节点的最小值,只要是连通图就好, ...
- char的越界赋值即其原理剖析
思考: int ch = 'A'; int ch1 = 65; int ch2 = 321; printf("%c %c %c\n", ch, ch1, ch2);的输出结果是什么 ...