zoukankan      html  css  js  c++  java
  • ORM操作mysql数据库

    orm介绍

    #ORM是“对象-关系-映射”的简称。(Object Relational Mapping,简称ORM)
    #类对象--->sql--->pymysql--->mysql服务端--->磁盘,orm其实就是将类对象的语法翻译成sql语句的一个引擎
    orm语句 -- sql -- 调用pymysql客户端发送sql -- mysql服务端接收到指令并执行
    

    连接数据库

    1#在django项目的配置文件中,修改链接数据库的配置,django默认链接自带数据库sqllite3,改成链接mysql数据库
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',#申明链接mysql
                'NAME':'orm01',		# 要连接的数据库,连接前需要创建好
                'USER':'root',		# 连接数据库的用户名
                'PASSWORD':'123456',# 连接数据库的密码
                'HOST':'127.0.0.1',  #IP地址
                'POST':3306,	#端口号
            }
            'app01': { #可以为每个app都配置自己的数据,并且数据库还可以指定别的,也就是不一定就是mysql,也可以指定sqlite等其他的数据库
                'ENGINE': 'django.db.backends.mysql',
                'NAME':'bms',           # 要连接的数据库,连接前需要创建好
                'USER':'root',        # 连接数据库的用户名
                'PASSWORD':'',        # 连接数据库的密码
                'HOST':'127.0.0.1',       # 连接主机,默认本级
                'PORT':3306            #  端口 默认3306
            }
     }
    2:#在项目的文件夹中的init文件中,申明使用pymysql模块链接mysql服务端,django默认使用mysqldb链接数据库服务端,mysqldb并不支持python3.4以上版本,用pymysql替换mysqldb;
        import pymysql
        pymysql.install_as_MySQLdb()
    3:#在应用的models文件中新建一个类:
        from django.db import models
        #类名就是新建的表的表名,orm要求每一个表中都必须有一个主键,没有设置就自动生成一个自增主键,叫ID字段
        class UserInfo(models.Model):
            #添加ID字段,AutoField为自增属性字段,参数是设置为主键,
            id=models.AutoField(primary_key=True)
            #添加一个name字段CharField代表varchar类型,参数max_length执行长度
            name=models.CharField(max_length=10)
            #Date类型,只有年月日,传入数据的时候必须是"2018-12-12"这种格式
            bday=models.DateField()
            #布尔值类型,数据库中bool值存储的是tinyInt类型,存的是0或者1数字
            checked=models.BooleanField()
    4:#执行数据库同步指令,
    	#生成记录,每次修改了models里面的内容或者添加了新的app,新的app里面写了models里面的内容,都要执行这两条
        #执行makemigrations命令会在当前应用中的migrations模块中生成一个记录,
    	python mange.py makemigrations
        #执行上面这个语句的记录来创建表,生成的表名字前面会自带应用的名字,
        #例如:你的book表在mysql里面叫做app01_book表
    	python manage.py migrate
    5:#往表中添加数据:
        #导入应用中的midels模块
        from app01 import models
        new_obj=models.UserInfo(
        	id=1,name='张达',bday='2019-09-10',chenked=1,)
        #save方法把上面的语句翻译成sql语句,然后调用pymysql,发送给mysql服务端,
        new_obj.save()
    

    增加数据

    '''方式一'''
    #导入应用中的midels模块
        from app01 import models
        #实例化对象,会把对象的参数,当作数据插入到数据库中
        new_obj=models.UserInfo(
        	id=1,name='张达',bday='2019-09-10',chenked=1,)
        #save方法把上面的语句翻译成sql语句,然后调用pymysql,发送给mysql服务端,
        new_obj.save()
    '''方式二'''
    	#new_obj是当前创建新的数据的model对象
        imnport datetime
        #传入的时间可以是获取的当前时间
        data_time=datetime.datetime.now()
    	new_obj=models.UserInfo.objects.create(
                id=1,name='张达',bday=data_time,checked=0
        )
        print(new_obj)#打印对象:UserInfo object
        print(new_obj.name)
    

    批量增加数据

    #导入应用中的midels模块
        from app01 import models
        #定义一个空的列表用来盛放所有的数据
        obj_list=[]
        #实例化对象,会把对象的参数,当作数据插入到数据库中
        for i in range(20):
            new_obj=models.UserInfo(
                id=i,name='张达'+i,bday=f'2019-09-{i+1}',chenked=1,)
            obj_list.append(new_obj)
        #bulk_create方法可以批量添加数据
        models.UserInfo.objects.bulk_create(obj_list)
    

    添加字段

    from django.db import models
    1:#在models文件中添加一个字段
        class UserInfo(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=10)
        bday=models.DateField()
        checked=models.BooleanField()
        #新增一个字段,orm添加字段,该字段不能为空,所以要么给默认值,要么设置它允许为空 null=True
        now=models.DateTimeField(null=True)
    2:#当models中的数据发生改变执行python mange.py makemigrations和python manage.py migrate指令
        python mange.py makemigrations  执行指令会产生一个新的记录,然后在执行migrate指令,发送数据到服务端
        
    '''DateTimeField时间问题'''
    	#DateTimeField设置参数auto_now_add=True,在添加数据的时候自动帮你添加当前时间
        #添加的事件存在时区问题,使用的时区是格林尼治(UTC)时区,
    	now=models.DateTimeField(auto_now_add=True,null=True)
        #auto_now属性更新数据时,自动添加更新当前时间,创建新数据时,也会自动添加时间
        now=models.DateTimeField(auto_now=True,null=True)
        #解决方法:
        	settings配置文件中将USE_TZ的值改为False:告诉mysql存储时间是按照当地时间来存储
            使用pycharm的数据库客户端的时候,时区也是utc时间,要注意修改
    

    删除数据

    1:#filter()简单查询
        返回的是queryset类型的数据,里面是一个个的model对象,类似于列表,因为查到的可能是多个数据
        #queryset对象删除数据,如果查询到的是多条数据,就会删除这些查到的所有数据
        models.UserInfo.objects.filter(id=7).delete()  
        #model对象调用删除,使用索引具体到某一条数据,删除只会删除这一条数据
        models.UserInfo.objects.filter(id=7)[0].delete()  
        #删除所有的数据
        models.UserInfo.objects.all().delete()
    

    修改数据

    #方式一:update
    	#update方法只能用queryset对象可以调用,model对象不能使用update方法
    	models.UserInfo.objects.filter(id=2).update(
             name='篮子文',
             checked = 0,)
    #方式二:
    	#使用model对象修改,直接设置值的方式直接修改
    	ret = models.UserInfo.objects.filter(id=2)[0]
        ret.name='lijie'
        ret.checked=1
        ret.save()#save提交数据
        
    #修改数据时时间auto_now参数:
    	# 更新记录时,自动更新时间,创建新纪录时也会帮你自动添加创建时的时间,但是在更新数据时只有使用save方法的方式2的形式更新才能自动更新时间,update方式不会生效,
        now2 = models.DateTimeField(auto_now=True,null=True)
    

    查询API

    #all() 查询所有
    	查询数据库中的所有结果,结果是queryset类型
        models.UserInfo.objects.all() 返回的数据库中所有的数据
    #filter() 条件查询
    	查询条件不能匹配到数据时,不会报错,返回一个空的queryset,<QuerySet []>,如果没有写查询条件会获取所有数据,获取的是queryset对象,queryset类型的数据还能够继续调用fitler方法
        ret = models.Book.objects.filter(title='金瓶7',publish='24期出版社')可以指定多个条件查询,相当于原生sql的and语句,
    #get() model对象查询
    	get获取的是一个model对象,有且只能有一个,查询不到,或者查询到多个都会报错
        1. 查不到数据会报错 :Book matching query does not exist
        2. 超过一个就报错 :returned more than one Book -- it returned 13!
    #exclude() 排除
    	指定排除与条件匹配的数据,返回值是queryset类型 
    	1.object能够调用,models.Book.objects.exclude(id=6)
        2.queryset类型数据能够调用, models.Book.objects.all().exclude(id=6)
    #order_by()排序
    	queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型
    	指定条件排序,可以指定多个排序字段,在条件中加上减号就是倒序排列
        models.Book.objects.all().order_by('-price','id')先根据price倒序排列,然后数据相同的再根据id排序
    #reverse() 反转
    	queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型,数据哟啊先排序再反转
        models.Book.objects.all().order_by('id').reverse()
    #count() 计数
    	queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量
        models.Book.objects.all().count() 查询一共有多少条数据
    #first()    
    	返回第一条数据,结果是model对象类型
        Book.objects.all()[0] = Book.objects.all().first()这两种写法的意思相同
    #last()
    	返回最后一条数据,结果是model对象类型
        Book.objects.all()[-1] = Book.objects.all().last()这两种写法的意思相同
    #exists()
    	判断返回结果集是不是有数据
     	queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False
        models.Book.objects.filter(id=9999).exists() #有结果就是True,没有结果就是False
    #values()
    	返回的queryset对象,里面的数据是字典的形式,每一条数据是一个字典,字段为键,数据为值,
        ret = models.Book.objects.filter(id=9).values('title','price') #条件查询返回一个字典
        ret = models.Book.objects.values() #返回所有的数据
    #values_list
    	返回的queryset,里面是数组类型数据,它返回的是一个元组序列,把一条数据封装成一个元祖
        ret = models.Book.objects.all().values_list('title','price')#返回的是一个元祖
        ret = models.Book.objects.values_list()#返回所有数据
    #distinct() 去重
    	values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录
        models.Book.objects.all().values('name').distinct()#吧name值相同的去除掉
    

    双下划线模糊查询

    Book.objects.filter(price__in=[100,200,300]) #price值等于这三个里面的任意一个的对象
    Book.objects.filter(price__gt=100)  #大于,大于等于是price__gte=100,别写price>100,这种参数不支持
    Book.objects.filter(price__lt=100)	#小于,小于等于是price__gte=100,别写price>100,这种参数不支持
    Book.objects.filter(price__range=[100,200])  #sql的between and,大于等于100,小于等于200
    Book.objects.filter(title__contains="python")  #title值中包含python的
    Book.objects.filter(title__icontains="python") #不区分大小写
    Book.objects.filter(title__startswith="py") #以什么开头,istartswith  不区分大小写
    Book.objects.filter(title__endswith="py") #以什么结尾,iendswith  不区分大小写
    Book.objects.filter(pub_date__year=2012) #查询时间是2012年的所有数据
    #某年某月某日:
    ret = models.Book.objects.filter(publish_date__year='2018') #查询时间是2018年的所有数据
    ret = models.Book.objects.filter(publish_date__year__gt='2018')#2018写数字也可以
    ret = models.Book.objects.filter(publish_date__year='2019',publish_date__month='8',
                                     publish_date__day='1')#2019-08-01的所有数据
    #找字段数据为空的双下滑线
    models.Book.objects.filter(publish_date__isnull=True) #publish_date这个字段值为空的那些数据
    

    多表表结构

    from django.db import models
    
    # Create your models here.
    
    class Author(models.Model):
        """
        作者表
        """
        name=models.CharField( max_length=32)
        age=models.IntegerField()
        # authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
        #与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以
        au=models.OneToOneField("AuthorDetail",on_delete=models.CASCADE)
    	#就是foreignkey+unique,只不过不需要我们自己来写参数了,并且orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为au_id
    class AuthorDetail(models.Model):
        """
        作者详细信息表
        """
        birthday=models.DateField()
        telephone=models.CharField(max_length=11)
        addr=models.CharField(max_length=64)
    class Publish(models.Model):
        """
        出版社表
        """
        name=models.CharField( max_length=32)
        city=models.CharField( max_length=32)
    
    class Book(models.Model):
        """
        书籍表
        """
        title = models.CharField( max_length=32)
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)
        publishs=models.ForeignKey(to="Publish",on_delete=models.CASCADE,)
        ## 通过ORM自带的ManyToManyField自动创建第三张表,与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表,并且注意一点,你查看book表的时候,你看不到这个字段,因为这个字段就是创建第三张表的意思,不是创建字段的意思,所以只能说这个book类里面有authors这个字段属性
        authors=models.ManyToManyField('Author',)
        
    '''********************************************************************'''
    #models.OneToOneField (to="Publish",to_field="nid",on_delete=models.CASCADE)
    	建立一对一的关系时候使用,to指向被关联的表,to_field指向你关联的字段,不写这个,默认会自动关联主键字段,on_delete级联删除
    #models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
    	建立一对多的关系的时候使用
    #models.ManyToManyField(to='Author',)    
    	建立多对多关系的时候使用,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表,并且注意一点,你查看表的时候,你看不到这个字段,因为这个字段就是创建第三张表的意思,不是创建字段的意思,所以只能说这个类里面有这个字段属性,产生的第三张表中有一个默认的id字段,然后是两张被关联表中的id字段,第三张表的表名是以两个被关联数据库的名字来命名,中间加上一个下划线,类名在前,属性在后
    '''所有的外键字段都会被自动加上_id字段.所有在建外键的时候,不要写_id,orm会自动帮你追加'''
    '''db_constrtaint=False'''消除外键的强制消除关系
    

    创建表时的元信息

    元信息
        ORM对应的类里面包含另一个Meta类,而Meta类封装了一些数据库的信息。主要字段如下:
    class Author2Book(models.Model):
        author = models.ForeignKey(to="Author")
        book = models.ForeignKey(to="Book")
        class Meta:
            unique_together = ("author", "book")
    
    #db_table
        ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。db_table = 'book_model'
    
    #index_together
        联合索引。
    
    #unique_together
        创建联合唯一索引。
    
    #ordering
        指定默认按什么字段排序。
        ordering = ['pub_date',]
        ordering = ['-id','pub_date']
        只有设置了该属性,我们查询到的结果才可以被reverse(),否则是能对排序了的结果进行反转(order_by()方法排序过的数据)
    
  • 相关阅读:
    【BZOJ 1013】 [JSOI2008]球形空间产生器sphere
    【codeforces 779A】Pupils Redistribution
    【codeforces 779B】Weird Rounding
    【codeforces 779C】Dishonest Sellers
    Residential Gateway System for Home Network Service
    互联网大规模数据分析技术(自主模式)第五章 大数据平台与技术 第10讲 大数据处理平台Hadoop
    大数据系统基础(自主模式) 2.1大数据和云计算关系概述
    设计模式(10) 外观模式(FACADE)
    命令模式(Command Pattern)
    设计模式(三)建造者模式Builder(创建型)
  • 原文地址:https://www.cnblogs.com/luckinlee/p/11622284.html
Copyright © 2011-2022 走看看