数据库开发-Django ORM的多对多查询
数据库开发-Django ORM的多对多查询
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.联合主键问题
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` smallint(6) NOT NULL DEFAULT '' COMMENT 'M=1, F=2',
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_no`),
UNIQUE KEY `dept_name` (`dept_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`),
KEY `dept_no` (`dept_no`),
CONSTRAINT `dept_emp_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees`
(`emp_no`) ON DELETE CASCADE,
CONSTRAINT `dept_emp_ibfk_2` FOREIGN KEY (`dept_no`) REFERENCES `departments`
(`dept_no`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
多对多建表语句
SQLAlchemy提供了联合主键支持,但是Django至今都没有支持。 Django只支持单一主键,这也是我提倡的。但对于本次基于Django测试的表就只能增加一个单一主键了。具体原因,请参看 https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys 。 Django 到目前为止也没有提供这种Composite primary key Django不能直接添加自己的2个字段的联合主键,我们手动为表创建一个自增id主键。操作顺序如下:
1. 取消表所有联合主键,并删除所有外键约束后保存,成功再继续
2. 为表增加一个id字段,自增、主键。保存,如果成功,它会自动填充数据
3. 重建原来的外键约束即可
二.构建模型
from django.db import models # Create your models here.
from django.db import models class Employee(models.Model):
class Meta:
db_table = 'employees' emp_no = models.IntegerField(primary_key=True)
birth_date = models.DateField(null=False)
first_name = models.CharField(null=False, max_length=14)
last_name = models.CharField(null=False, max_length=16)
gender = models.SmallIntegerField(null=False)
hire_date = models.DateField(null=False) def __repr__(self):
return "<Employee: {} {} {}>".format(
self.emp_no,
self.first_name,
self.last_name
) __str__ = __repr__ class Department(models.Model):
class Meta:
db_table = 'departments' dept_no = models.CharField(primary_key=True, max_length=4)
dept_name = models.CharField(max_length=40, null=False, unique=True) def __repr__(self):
return "<Department: {} {}>".format(
self.dept_no,
self.dept_name
) __str__ = __repr__ class Dept_emp(models.Model):
class Meta:
db_table = 'dept_emp' id = models.AutoField(primary_key=True) # 新增自增主键,解决不支持联合主键问题
emp_no = models.ForeignKey(to='Employee', on_delete=models.CASCADE,db_column='emp_no') #写模块.类名,当前模块写类名
dept_no = models.ForeignKey(to='Department', on_delete=models.CASCADE,max_length=4,db_column='dept_no') # django会给外键字段自动加后缀_id,如果不需要加这个后缀,用db_column指定
from_date = models.DateField(null=False)
to_date = models.DateField(null=False) def __repr__(self):
return "<DeptEmp: {} {}>".format(
self.emp_no,
self.dept_no
) __str__ = __repr__
三.多对多查询案例
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie import os
import django #参考salary/wsgi.py文件
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'salary.settings')
django.setup(set_prefix=False) #导入employee应用的models模块中定义的Employee类
from employee.models import Employee,Department empmgr = Employee.objects
deptmgr = Department.objects
# 查询10010员工的所在的部门编号及员工信息
emp = empmgr.filter(pk=10010).get() # 只查employees
print('-' * 30)
depts = emp.dept_emp_set.all() # 懒查
for x in depts: # 查dept_emp中的2个部门,然后再查departments 2次
print(type(x), x) #
e = x.emp_no #
print(type(e), e)
d = x.dept_no #
print(type(d), d)
print()
print(e.emp_no, e.first_name, e.last_name, d.dept_no, d.dept_name)
------------------------------
(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None
(0.001) SELECT `employees`.`emp_no`, `employees`.`birth_date`, `employees`.`first_name`, `employees`.`last_name`, `employees`.`gender`, `employees`.`hire_date` FROM `employees` WHERE `employees`.`emp_no` = 10010; args=(10010,)
<class 'employee.models.Dept_emp'> <DeptEmp: <Employee: 10010 Duangkaew Piveteau> <Department: d004 Production>>
(0.001) SELECT `dept_emp`.`id`, `dept_emp`.`emp_no`, `dept_emp`.`dept_no`, `dept_emp`.`from_date`, `dept_emp`.`to_date` FROM `dept_emp` WHERE `dept_emp`.`emp_no` = 10010; args=(10010,)
<class 'employee.models.Employee'> <Employee: 10010 Duangkaew Piveteau>
(0.001) SELECT `departments`.`dept_no`, `departments`.`dept_name` FROM `departments` WHERE `departments`.`dept_no` = 'd004'; args=('d004',)
<class 'employee.models.Department'> <Department: d004 Production> (0.001) SELECT `departments`.`dept_no`, `departments`.`dept_name` FROM `departments` WHERE `departments`.`dept_no` = 'd006'; args=('d006',)
10010 Duangkaew Piveteau d004 Production
<class 'employee.models.Dept_emp'> <DeptEmp: <Employee: 10010 Duangkaew Piveteau> <Department: d006 Quality Management>>
<class 'employee.models.Employee'> <Employee: 10010 Duangkaew Piveteau>
<class 'employee.models.Department'> <Department: d006 Quality Management> 10010 Duangkaew Piveteau d006 Quality Management
以上代码执行结果戳这里
五.总结
在开发中,一般都会采用ORM框架,这样就可以使用对象操作表了。 Django中,定义表映射的类,继承自Model类。Model类使用了元编程,改变了元类。 使用Field实例作为类属性来描述字段。
使用ForeignKey来定义外键约束。
是否使用外键约束?
力挺派
能使数据保证完整性一致性,Django属于力挺派系列的软件。
弃用派
开发难度增加,大量数据的时候影响插入、修改、删除的效率。 在业务层保证数据的一致性。
数据库开发-Django ORM的多对多查询的更多相关文章
- 数据库开发-Django ORM的一对多查询
数据库开发-Django ORM的一对多查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.联合主键问题 CREATE TABLE `employees` ( `emp_no` ...
- 数据库开发-Django ORM的单表查询
数据库开发-Django ORM的单表查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询集 1>.查询集相关概述 查询会返回结果的集,它是django.db.mod ...
- 数据库开发-Django ORM的数据库迁移
数据库开发-Django ORM的数据库迁移 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. Django 项目准备 1>.安装django包 pip install d ...
- Django ORM --- 建表、查询、删除基础
1.什么是ORM ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的 ...
- Django学习——静态文件配置、request对象方法、pycharm如何链接数据库、Django如何指定数据库、Django orm操作
静态文件配置 # 1.静态文件 网站所使用的已经提前写好的文件 css文件 js文件 img文件 第三方文件 我们在存储静态文件资源的时候一般默认都是放在static文件夹下 # 2.Django静态 ...
- 数据库:django ORM如何处理N+1查询
数据库N+1查询是个常见的问题,简单描述场景如下 基本场景 class Category(models.Model): name = models.CharField(max_length=30) c ...
- Django ORM中的模糊查询
ORM映射 什么是ORM映射?在笔者认为就是对SQL语句的封装,所写语句与SQL对应语句含义相同,使开发更加简单方便,不过也是存在弊端的,使程序运行效率下降.例如: UserInfo.objects. ...
- Django orm 常用查询筛选总结
本文主要列举一下django orm中的常用查询的筛选方法: 大于.大于等于 小于.小于等于 in like is null / is not null 不等于/不包含于 其他模糊查询 model: ...
- 优化Django ORM中的性能问题(含prefetch_related 和 select_related)
Django是个好工具,使用的很广泛. 在应用比较小的时候,会觉得它很快,但是随着应用复杂和壮大,就显得没那么高效了.当你了解所用的Web框架一些内部机制之后,才能写成比较高效的代码. 怎么查问题 W ...
随机推荐
- svn"重新定位"提示版本库uuid不匹配
svn"重新定位"提示版本库 uuid不匹配: 版本库 "https://wolfcome110/svn/andon" 的 uuid是 "d52648 ...
- Zabbix使用主动模式进行监控配置方法
一直都是在用Zabbix的被动模式(即默认模式)进行监控. 但是总有些情况是不适用被动模式的,刚好工作上有这个需求,于是捣鼓了一下,发现配置起来也挺简单的. (1)Agent配置 修改Zabbix-a ...
- Ubuntu搭建交叉编译开发环境
在Linux驱动开发过程中,往往需要搭建交叉编译开发环境,其中,最重要的环节就是安装交叉编译工具链,本文介绍如何在Ubuntu下搭建交叉编译开发环境. 1.官网下载交叉编译工具链 链接如下: http ...
- centos个性化命令行提示符
为了在满屏的命令中找到用户的命令行,所以很有必要设置一种字体颜色.我就设置最实用的一种,可以用蓝色字体显示当前所在路径 命令行输入: echo "PS1='[\${debian_chroot ...
- 一致性hash算法应用场景、详解与实现(JAVA)
一.概述 在分布式环境下,开发者通常会遇到一些分布存储的场景,例如数据库的分库分表(比如用户id尾号为1的放入数据库1,id尾号为2的放入数据库2):又如分布式缓存数据的获取(比如根据ip地址进行缓存 ...
- cisco ap客户端无规律掉线
设备 cisco air-ct2504-50-k9 cisco air-ap1832I-H-k9 首先根据这个帖子 https://community.cisco.com/t5/other-wirel ...
- 简述 高性能Linux服务器 模型架构 设计
主要从三个方面进行分析: 1.事件处理模式 2.并发模式 一.事件处理模式 1.Reactoor模式 定义: 主线程只负责监听文件描述符上是否有事件发生,有的话立即将该事件通知工作线程,除此之外,主线 ...
- Lock Free (无锁并发)
CAS( compare and swap) 原子操作,保证了如果需要更新的地址没有被其他进程(线程)改动过,那么它可以安全的写入.而这也是我们对于某个数据或者数据结构加锁要保护的内容,保证读写的一致 ...
- easyui中formatter的用法
easyui中formatter的用法 当我们使用easyui需要对某一列进行格式化处理value数据时,可以使用formatter进行格式化 这里以一个商品表举例,商品表中有一个商品类型的字段,数据 ...
- python 通过Sybase ASE ODBC Driver访问sybase数据库,无需配置DSN【自己整理的】
Python语言对于开发工程师或者测试工程师来说,应该是最高效的开发语言之一.但python访问sybase数据库的资料相对少见.而且sybase字符集为GB1803时,python访问sybase库 ...