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()方法排序過的數據)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM