MySQL:PyMySQL&ORM

1、PyMySQL介紹

PyMySQL 是在 Python3.x 版本中用於鏈接 MySQL 服務器的一個庫,Python2中則使用mysqldb。html

Django中也能夠使用PyMySQL鏈接MySQL數據庫。python

pip install pymysql   #安裝pymysql

2、鏈接數據庫

注意事項

在進行本文如下內容以前須要注意:mysql

  • 你有一個MySQL數據庫,而且已經啓動。
  • 你有能夠鏈接該數據庫的用戶名和密碼
  • 你有一個有權限操做的database

基本使用

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
# 定義要執行的SQL語句
sql = """
CREATE TABLE USER1 (
id INT auto_increment PRIMARY KEY ,
name CHAR(10) NOT NULL UNIQUE,
age TINYINT NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;
"""
# 執行SQL語句
cursor.execute(sql)
# 關閉光標對象
cursor.close()
# 關閉數據庫鏈接
conn.close()

返回字典格式數據

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句而且將結果做爲字典返回的遊標
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)#重點在加入括號的這行參數
# 定義要執行的SQL語句
sql = """
CREATE TABLE USER1 (
id INT auto_increment PRIMARY KEY ,
name CHAR(10) NOT NULL UNIQUE,
age TINYINT NOT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;
"""
# 執行SQL語句
cursor.execute(sql)
# 關閉光標對象
cursor.close()
# 關閉數據庫鏈接
conn.close()

注意:sql

charset=「utf8」,編碼不要寫成"utf-8"數據庫

3、增刪改查操做

增長

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
sql = "INSERT INTO USER1(name, age) VALUES (%s, %s);"
username = "Alex"
age = 18
# 執行SQL語句
cursor.execute(sql, [username, age])
# 提交事務
conn.commit()
cursor.close()
conn.close()

插入數據失敗回滾

在執行增刪改操做時,若是不想提交前面的操做,能夠使用 rollback() 回滾取消操做。django

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
sql = "INSERT INTO USER1(name, age) VALUES (%s, %s);"
username = "Alex"
age = 18
try:
    # 執行SQL語句
    cursor.execute(sql, [username, age])
    # 提交事務
    conn.commit()
except Exception as e:
    # 有異常,回滾事務
    conn.rollback()
cursor.close()
conn.close()

獲取插入數據的ID

(關聯操做時會用到)重點!服務器

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
sql = "INSERT INTO USER1(name, age) VALUES (%s, %s);"
username = "Alex"
age = 18
try:
    # 執行SQL語句
    cursor.execute(sql, [username, age])
    # 提交事務
    conn.commit()
    # 提交以後,獲取剛插入的數據的ID  重點在此處lastrowid
    last_id = cursor.lastrowid
except Exception as e:
    # 有異常,回滾事務
    conn.rollback()
cursor.close()
conn.close()

批量執行

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
sql = "INSERT INTO USER1(name, age) VALUES (%s, %s);"
data = [("Alex", 18), ("Egon", 20), ("Yuan", 21)]
try:
    # 批量執行多條插入SQL語句 executemany
    cursor.executemany(sql, data)
    # 提交事務
    conn.commit()
except Exception as e:
    # 有異常,回滾事務
    conn.rollback()
cursor.close()
conn.close()

刪除

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
sql = "DELETE FROM USER1 WHERE id=%s;"
try:
    cursor.execute(sql, [4])
    # 提交事務
    conn.commit()
except Exception as e:
    # 有異常,回滾事務
    conn.rollback()
cursor.close()
conn.close()

修改

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
# 修改數據的SQL語句
sql = "UPDATE USER1 SET age=%s WHERE name=%s;"
username = "Alex"
age = 80
try:
    # 執行SQL語句
    cursor.execute(sql, [age, username])
    # 提交事務
    conn.commit()
except Exception as e:
    # 有異常,回滾事務
    conn.rollback()
cursor.close()
conn.close()

查詢

查詢單條數據

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
# 查詢數據的SQL語句
sql = "SELECT id,name,age from USER1 WHERE id=1;"
# 執行SQL語句
cursor.execute(sql)
# 獲取單條查詢數據 fetchone
ret = cursor.fetchone()
cursor.close()
conn.close()
# 打印下查詢結果
print(ret)

查詢多條數據

# 導入pymysql模塊
import pymysql
# 鏈接database
conn = pymysql.connect(host=「你的數據庫地址」, user=「用戶名」,password=「密碼」,database=「數據庫名」,charset=「utf8」)
# 獲得一個能夠執行SQL語句的光標對象
cursor = conn.cursor()
# 查詢數據的SQL語句
sql = "SELECT id,name,age from USER1;"
# 執行SQL語句
cursor.execute(sql)
# 獲取多條查詢數據fetchall
ret = cursor.fetchall()
cursor.close()
conn.close()
# 打印下查詢結果
print(ret)

進階用法

# 能夠獲取指定數量的數據
cursor.fetchmany(3)
# 光標按絕對位置移動1
cursor.scroll(1, mode="absolute")
# 光標按照相對位置(當前位置)移動1
cursor.scroll(1, mode="relative")

 4、ORM(對象關係映射)

  ORM相關操做詳細session

    orm:
                         類      ----> 表
                    對象實例 ----> 表的記錄

一、對django模型的配置:

- settings的配置:

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',   注意查看有無新建的app
        ]

- 更改一下數據庫的配置:

    DATABASES = {
        # 'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # }
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 數據庫名稱,
            'USER': 'root',
            'PASSWORD': '',
            'CHARSET': 'utf8',
            'HOST': '127.0.0.1',
            'PORT':3306
        }
    }

- init.py:
    import pymysql
    pymysql.install_as_MySQLdb()

二、運行以下命令(建立表時):

python3 manage.py makemigrations   ====> 生成數據庫文件
python3 manage.py migrate          ====> 執行生成的數據庫文件

三、 Django中 app 中 models.py 以下示例(建立表)

from django.db import models

# Create your models here.

class classes(models.Model):
    id = models.AutoField(primary_key=True)
    classname = models.CharField(max_length=32, null=False, default='')

class students(models.Model):
    #不寫id orm 會自動生成一個 id字段
    student_name = models.CharField(max_length=32, null=False, default='')
    classes = models.ForeignKey('classes', on_delete=None)

class test(models.Model):
    age = models.IntegerField()


class teacher(models.Model):
    tname = models.CharField(max_length=32, null=False, default='')


class teacher2class(models.Model):
    teacher = models.ForeignKey('teacher', on_delete=None)
    classes = models.ForeignKey('classes', on_delete=None)

#多對多建立另一種方式
classes = models.ManyToManyField('classes')  #不建立關聯表  在teacher表加這個字段,Django會自動生成第三張表:PS:建議使用上面的方式,語義直白

四、 Django 中 app 中 views 以下示例

一、添加數據

    # models.表對象.objects.方法
    models.classes.objects.create(classname='高二1班')
    li = [
        models.classes(classname='高二5班'),
        models.classes(classname='高二3班'),
        models.classes(classname='高二6'),
    ]
    models.classes.objects.bulk_create(li)

二、查詢數據

from django.shortcuts import render, HttpResponse
from app01 import models
# Create your views here.

    # 獲取全部的數據=====> select * from classses;
    res = models.classes.objects.all()
    #<QuerySet [
              <classes: classes object (1)>,
              <classes: classes object (2)>,
              <classes: classes object (3)>,
              <classes: classes object (4)>
     ]>
    for item in res:
        print(item.id , item.classname)

    #獲取classname    ====> select classname from classses;
    #<QuerySet [
          {'classname': '高二1班'},
          {'classname': '高二2班'},
          {'classname': '高二3班'},
          {'classname': '高二4班'}
     ]>
    res = models.classes.objects.values('classname').all()
    print(res)#列表字典格式

    for item in res:
        print(item['classname'])


    #value_list:
        <QuerySet [('高二1班',), ('高二2班',), ('高二3班',), ('高二4班',)]>
    res = models.classes.objects.values_list('classname').all()
    print(res)


    2.1 取第一條  ---> select * from classes limit 1;
    res = models.classes.objects.first()
    print(res.classname)


    2.2 根據條件查詢數據
    res = models.classes.objects.filter(id=4)

3. 刪除  ---> delete from classes where id=1;

models.classes.objects.filter(id=4).delete()

4. 更新

models.classes.objects.filter(id=3).update(classname='高二10班')

5. 一對多添加

    models.students.objects.create(student_name='王剛蛋', classes_id=1)
    models.students.objects.create(student_name='王鐵錘', classes_id=2)
    models.students.objects.create(student_name='二狗', classes_id=3)
    models.students.objects.create(student_name='劉dd', classes_id=1)
    models.students.objects.create(student_name='狗剩子', classes_id=2)
    models.students.objects.create(student_name='鐵蛋', classes_id=3)
    models.students.objects.create(student_name='xxxx', classes_id=3)
View Code

6.正向查詢

    # 外鍵(FK) classes_id 代指 --->  classes表裏面的一行記錄
       # sql   :select * from classes left join students on claess.id =stdents.classid;
   # res.query:SELECT `app01_students`.`id`, `app01_students`.`student_name`, `app01_students`.`classes_id`  FROM `app01_students`
    res = models.students.objects.all()
    for item in res:
        print(item.id, item.student_name,  item.classes.classname)#此處classes爲建表時的外鍵名稱

7. 反向查詢

     #高二1班有多少學生? obj.表名_set.all()
    sql : select * from classes where classname='高二1班'
        7.1先查詢班級表 班級名爲高二1班的
        res = models.classes.objects.filter(classname='高二1班').first()
        7.2再查詢學生表中全部符合的
        info = res.students_set.all()
        # select * from students where classes_id =  res['id']
        print(info)
        for item in info:
            print(item.student_name)

8. __ 神奇的雙下劃線

    res = models.students.objects.filter(classes__classname='高二1班').all()
    #至關於執行下面的sql語句,連表查詢妙用
    print(res.query)
    #SELECT `app01_students`.`id`,
           `app01_students`.`student_name`,
           `app01_students`.`classes_id`
    FROM `app01_students` INNER JOIN `app01_classes` ON (`app01_students`.`classes_id` = `app01_classes`.`id`) WHERE `app01_classes`.`classname` = 高二1班
    for item in res:
        print(item.student_name)

9. 獲取個數 ---> count() ==> select count(*) from  students

cnt = models.classes.objects.count()
print(cnt)

10. 大於,小於

    greater then 大於
    res = models.classes.objects.filter(id__gt=1) #大於
    res = models.classes.objects.filter(id__gte=1)#大於等於
    res = models.classes.objects.filter(id__lt=1) #小於
    res = models.classes.objects.filter(id__lte=1)#小於等於
    sql :select * from classes where id < 10 and id > 1
    res = models.classes.objects.filter(id__lt=10, id__gt=1)   # 獲取id小於10 且 大於1的值

11. in 判斷在不在

    exclude : 除去xxx ,還剩xxxx
    res = models.classes.objects.filter(id__in=[11, 22, 33])   # 獲取id等於十一、2二、33的數據
    res = models.classes.objects.exclude(id__in=[11, 22, 33])  # not in

12. isnull

  res = models.classes.objects.filter(id__isnull=True)

13. contains 模糊查詢

    select * from stundets where student_name like '%二%';
    contains 至關於 like
    startswith == > like 'ven%',istartswith, endswith ===> like '%ven', iendswith,
    res = models.classes.objects.filter(classname__contains="ven")
    res = models.classes.objects.filter(classname__icontains="ven") # icontains大小寫不敏感(不區分大小寫)
    models.classes.objects.exclude(classname__icontains="ven") #判斷字符中沒有ven 的數據

14. range 範圍

res = models.classes.objects.filter(id__range=[1, 2])   # 範圍bettwen and

15. order by 排序

models.classes.objects.filter(name='seven').order_by('id')  # asc 升序
models.Tb1.objects.filter(name='seven').order_by('-id')   # desc 降序

16. group by 分組查詢

from django.db.models import Count, Min, Max, Sum
    res = models.students.objects.values('classes_id').annotate(c=Count('id')) #根據classes_id分組
    SELECT `app01_students`.`classes_id`,
    COUNT(`app01_students`.`id`) AS `c` FROM `app01_students` GROUP BY `app01_students`.`classes_id` ORDER BY NULL

17. limit、offset 切片

res = models.students.objects.all()[10:20] #從第10行開始取:取20條
    print(res.query)

18. F F() 的實例能夠在查詢中引用字段,來比較同一個 model 實例中兩個不一樣字段的值。

from django.db.models import F
    #對id=1的人 在age字段上 數據+1
    models.students.objects.filter(id=1).update(age=F('age') + 1) #對兩個字段的值作比較和操做

19. Q  執行更復雜的查詢(或例如OR語句),你能夠使用Q對象

from django.db.models import F, Q

    Q(nid=8) | Q(nid__gt=10)
    res = models.students.objects.filter(Q(id=8) | Q(id__gt=10)) #取id=8 或者 id>10 的數據
    print(res.query)
   # SELECT `app01_students`.`id`, `app01_students`.`student_name`, `app01_students`.`classes_id` FROM `app01_students` WHERE (`app01_students`.`id` = 8 OR `app01_students`.`id` > 10)


    Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    #取id=8 或者 id>10 而且 名字爲root 的 數據
    res = models.students.objects.filter(Q( Q(id=8) | Q(id__gt=10)) & Q(student_name='root'))
    print(res.query)

20. 執行原生SQL Django的orm沒法知足時

from django.db import connection, connections  #一個鏈接默認數據庫,一個能夠選擇數據庫
    cursor = connection.cursor() #connection會去settings找數據庫配置
    cursor = connections['xxx'].cursor() #這是鏈接另外一個主機的方式

    cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    res = cursor.fetchone()
    .
    .

21. 多對多查詢

1. 反向查詢:
        res = models.teacher.objects.filter(tname='eagon').first()
    1、obj.表類名小寫_set.all()
        info = res.teacher2class_set.all()  #查詢老師名爲eagon 所代課的 班級名
    二、在models中的表類的ForeignKey('teacher', on_delete=None,related_name = 'classes')
        info = res.classes.all()
        for item in info:
            item.classes.classname
    
2. 神器的雙下滑線查詢
    res = models.teacher2class.objects.filter(teacher__tname='eagon')
    for item in res:
        item.classes.classname

最後補充 Djangoadmin 的配置 (admin是Django自帶的一個後臺管理系統)

  •     admin.py中,註冊表
    • admin.site.register(models.表名)
  •     urls 中
    • url('admin', admin.site.urls)
  •     命令行建立
    • python3 manage.py createsupperuser
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息