[Notes] python python MySQL et MySQL opération interactive

[Notes] python python MySQL et MySQL opération interactive

annuaire

1. Préparation des données

2. SQL Walkthrough

2.1 instruction SQL exercices de renforcement

2,2 La répartition de la table dans une pluralité de tables

opération MySQL 3. python

3.1. Procédé de fonctionnement Python MySQL

3.2. Les opérations de requête de base

3.3. Opérations de base CRUD

3.4. Paramétrisation

penser


1. Préparation des données

Créer une bibliothèque jing_dong, bibliothèque créer une table de marchandises, et insérez les données pour les exercices d'instructions SQL.

-- 创建 "京东" 数据库
create database jing_dong charset=utf8;

-- 使用 "京东" 数据库
use jing_dong;

-- 创建一个商品goods数据表
create table goods(
    id int unsigned primary key auto_increment not null,
    name varchar(150) not null,
    cate_name varchar(40) not null,
    brand_name varchar(40) not null,
    price decimal(10,3) not null default 0,
    is_show bit not null default 1,
    is_saleoff bit not null default 0
);


-- 向goods表中插入一些数据
insert into goods values(0,'r510vc 15.6英寸笔记本','笔记本','华硕','3399',default,default); 
insert into goods values(0,'y400n 14.0英寸笔记本电脑','笔记本','联想','4999',default,default);
insert into goods values(0,'g150th 15.6英寸游戏本','游戏本','雷神','8499',default,default); 
insert into goods values(0,'x550cc 15.6英寸笔记本','笔记本','华硕','2799',default,default); 
insert into goods values(0,'x240 超极本','超级本','联想','4880',default,default); 
insert into goods values(0,'u330p 13.3英寸超极本','超级本','联想','4299',default,default); 
insert into goods values(0,'svp13226scb 触控超极本','超级本','索尼','7999',default,default); 
insert into goods values(0,'ipad mini 7.9英寸平板电脑','平板电脑','苹果','1998',default,default);
insert into goods values(0,'ipad air 9.7英寸平板电脑','平板电脑','苹果','3388',default,default); 
insert into goods values(0,'ipad mini 配备 retina 显示屏','平板电脑','苹果','2788',default,default); 
insert into goods values(0,'ideacentre c340 20英寸一体电脑 ','台式机','联想','3499',default,default); 
insert into goods values(0,'vostro 3800-r1206 台式电脑','台式机','戴尔','2899',default,default); 
insert into goods values(0,'imac me086ch/a 21.5英寸一体电脑','台式机','苹果','9188',default,default); 
insert into goods values(0,'at7-7414lp 台式电脑 linux )','台式机','宏碁','3699',default,default); 
insert into goods values(0,'z220sff f4f06pa工作站','服务器/工作站','惠普','4288',default,default); 
insert into goods values(0,'poweredge ii服务器','服务器/工作站','戴尔','5388',default,default); 
insert into goods values(0,'mac pro专业级台式电脑','服务器/工作站','苹果','28888',default,default); 
insert into goods values(0,'hmz-t3w 头戴显示设备','笔记本配件','索尼','6999',default,default); 
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default); 
insert into goods values(0,'x3250 m4机架式服务器','服务器/工作站','ibm','6888',default,default); 
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);

Remarque: vous voulez insérer une valeur par défaut lorsque, si la clé primaire, 0, null, par défaut peut être . Si la clé non primaire, vous ne pouvez utiliser par défaut .

 

2. SQL Walkthrough

 

2.1 instruction SQL exercices de renforcement

Sur la base du tableau de données ci-dessus, mettre en pratique certaines des déclarations.

-- 查询类型cate_name为 '超极本' 的商品名称、价格
select name , price from goods where cate_name="超级本";
select name as 商品名称, price as 商品价格 from goods where cate_name="超级本";
+-----------------------------+--------------+
| 商品名称                    | 商品价格     |
+-----------------------------+--------------+
| x240 超极本                 |     4880.000 |
| u330p 13.3英寸超极本        |     4299.000 |
| svp13226scb 触控超极本      |     7999.000 |
+-----------------------------+--------------+

-- 显示商品的种类
select distinct cate_name from goods;
select cate_name from goods group by cate_name;
+---------------------+
| cate_name           |
+---------------------+
| 笔记本              |
| 游戏本              |
| 超级本              |
| 平板电脑            |
| 台式机              |
| 服务器/工作站       |
| 笔记本配件          |
+---------------------+

-- 显示商品种类中具体的商品的名称
select cate_name, group_concat(name) from goods group by cate_name;

-- 求所有电脑产品的平均价格,并且保留两位小数
select avg(price) from goods;
select round(avg(price),2) as avg_price from goods;
+---------------------+
| round(avg(price),2) |
+---------------------+
|             5570.57 |
+---------------------+

-- 显示每种类型商品的平均价格
select cate_name,avg(price) from goods group by cate_name;  -- 执行时先group by,再avg(price)

-- 查询每种类型的商品中 最贵、最便宜、平均价、数量
select cate_name,max(price),min(price),avg(price),count(*) from goods group by cate_name;

-- 查询所有价格大于平均价格的商品,并且按价格降序排序(注:子查询中先查出平均价格)
select id,name,price from goods 
where price > (select round(avg(price),2) as avg_price from goods) 
order by price desc;

-- 查询每种类型中最贵的价格
select cate_name , max(price) from goods group by cate_name;
-- 查询每种类型中最贵的电脑信息  (先把子查询结果当作一个表,再用连接查询,条件是连个表相应的字段信息相等)
select * from goods
inner join 
    (
        select
        cate_name, 
        max(price) as max_price, 
        min(price) as min_price, 
        avg(price) as avg_price, 
        count(*) from goods group by cate_name
    ) as goods_new_info 
on goods.cate_name=goods_new_info.cate_name and goods.price=goods_new_info.max_price;

-- 完善上一句查询,让同一种类型最高价的不止一个型号时,这些型号能显示在一起(用 order by)
select * from goods
inner join 
    (
        select
        cate_name, 
        max(price) as max_price, 
        min(price) as min_price, 
        avg(price) as avg_price, 
        count(*) from goods group by cate_name
    ) as goods_new_info 
on goods.cate_name=goods_new_info.cate_name and goods.price=goods_new_info.max_price order by goods_new_info.cate_name;

-- 查询每种类型中最贵的电脑的类型、名字和价格
select goods.cate_name,goods.name,goods.price from goods
inner join 
    (
        select
        cate_name, 
        max(price) as max_price, 
        min(price) as min_price, 
        avg(price) as avg_price, 
        count(*) from goods group by cate_name
    ) as goods_new_info 
on goods.cate_name=goods_new_info.cate_name and goods.price=goods_new_info.max_price order by goods_new_info.cate_name;
+---------------------+---------------------------------------+-----------+
| cate_name           | name                                  | price     |
+---------------------+---------------------------------------+-----------+
| 台式机              | imac me086ch/a 21.5英寸一体电脑       |  9188.000 |
| 平板电脑            | ipad air 9.7英寸平板电脑              |  3388.000 |
| 服务器/工作站       | mac pro专业级台式电脑                 | 28888.000 |
| 游戏本              | g150th 15.6英寸游戏本                 |  8499.000 |
| 笔记本              | y400n 14.0英寸笔记本电脑              |  4999.000 |
| 笔记本配件          | hmz-t3w 头戴显示设备                  |  6999.000 |
| 超级本              | svp13226scb 触控超极本                |  7999.000 |
+---------------------+---------------------------------------+-----------+

 

2,2 La répartition de la table dans une pluralité de tables

(Note: cela ne divise pas en fait la table, mais d'abord la conception d'une bonne table de données)

Est une seule table (marchandise de table), les ajouts et suppressions de gestion du changement des données de recherche est compliquée, etc., devrait être une grande table de la division appropriée.

Tels que:

Le tableau original [produits] (id, nom, cate_name, BRAND_NAME, prix, is_show, is_saleoff)

Split pour le classement des marchandises [goods_cates] (id, nom) 

table de marque [] (id, nom)

........

Des mises à jour de la table des marchandises, des données de synchronisation, telles que cate_name cate_id à jour, brand_id BRAND_NAME mis à jour ...

 

Créer liste « Catégories »

Catégories créer des tableaux et des données d'insertion:

-- 创建商品分类表
create table if not exists goods_cates(
    id int unsigned primary key auto_increment,
    name varchar(40) not null
);

-- 查询原goods表中商品的种类
select cate_name from goods group by cate_name;

-- 将goods表中分组查询的结果,即商品的种类写入到goods_cates数据表(把查询结果当作信息插入到goods_cates 表中,不用像一般插入一样写value)
insert into goods_cates (name) select cate_name from goods group by cate_name;

--查询goods_cates表
select * from goods_cates;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | 台式机              |
|  2 | 平板电脑            |
|  3 | 服务器/工作站       |
|  4 | 游戏本              |
|  5 | 笔记本              |
|  6 | 笔记本配件          |
|  7 | 超级本              |
+----+---------------------+


 

synchronisation des données

Après séparation de la table goods_cates, la table est mise à jour sur les marchandises, les données de synchronisation. Les marchandises table de données est mis à jour par les goods_cates de table de données. Les champs de données mises à jour cate_name correspondant cate_id, et met à jour les données.

-- 通过goods_cates数据表来更新goods表
--(g.cate_name=c.name判断两个表对应的字段值相同时,更新goods表的cate_name数据为相应的id)
update goods as g ...... set g.cate_name=...
update goods as g inner join goods_cates as c on g.cate_name=c.name set g.cate_name=c.id;
-- 更新后,类别名放到了另一个表,cate_name更新为类别对应的id
+----+---------------------------------------+-----------+------------+-----------+---------+------------+
| id | name                                  | cate_name | brand_name | price     | is_show | is_saleoff |
+----+---------------------------------------+-----------+------------+-----------+---------+------------+
|  1 | r510vc 15.6英寸笔记本                 | 5         | 华硕       |  3399.000 |        |            |
|  2 | y400n 14.0英寸笔记本电脑              | 5         | 联想       |  4999.000 |        |            |
|  3 | g150th 15.6英寸游戏本                 | 4         | 雷神       |  8499.000 |        |            |
|  4 | x550cc 15.6英寸笔记本                 | 5         | 华硕       |  2799.000 |        |            |
|  5 | x240 超极本                           | 7         | 联想       |  4880.000 |        |            |
|  6 | u330p 13.3英寸超极本                  | 7         | 联想       |  4299.000 |        |            |
|  7 | svp13226scb 触控超极本                | 7         | 索尼       |  7999.000 |        |            |
|  8 | ipad mini 7.9英寸平板电脑             | 2         | 苹果       |  1998.000 |        |            |
|  9 | ipad air 9.7英寸平板电脑              | 2         | 苹果       |  3388.000 |        |            |
| 10 | ipad mini 配备 retina 显示屏          | 2         | 苹果       |  2788.000 |        |            |
| 11 | ideacentre c340 20英寸一体电脑        | 1         | 联想       |  3499.000 |        |            |
| 12 | vostro 3800-r1206 台式电脑            | 1         | 戴尔       |  2899.000 |        |            |
| 13 | imac me086ch/a 21.5英寸一体电脑       | 1         | 苹果       |  9188.000 |        |            |
| 14 | at7-7414lp 台式电脑 linux )          | 1         | 宏碁       |  3699.000 |        |            |
| 15 | z220sff f4f06pa工作站                 | 3         | 惠普       |  4288.000 |        |            |
| 16 | poweredge ii服务器                    | 3         | 戴尔       |  5388.000 |        |            |
| 17 | mac pro专业级台式电脑                 | 3         | 苹果       | 28888.000 |        |            |
| 18 | hmz-t3w 头戴显示设备                  | 6         | 索尼       |  6999.000 |        |            |
| 19 | 商务双肩背包                          | 6         | 索尼       |    99.000 |        |            |
| 20 | x3250 m4机架式服务器                  | 3         | ibm        |  6888.000 |        |            |
| 21 | 商务双肩背包                          | 6         | 索尼       |    99.000 |        |            |
+----+---------------------------------------+-----------+------------+-----------+---------+------------+

Cependant, si à ce moment marchandises desc, trouveront que bien que les types de produits sont id stockés, mais les produits sont cate_name type varchar et goods_cates est le type id int (à et goods_cates desc structure de table modifiée ). Et les deux tables ne sont pas associés, lorsque les biens de valeur à cate_name insérés, et ne vérifie pas (par goods_cates clé étrangère ).

Structure de table modifiée de l'instruction alter table par

-- 改cate_name为 cate_id,并修改Type
alter table goods  
change cate_name cate_id int unsigned not null;


-- 语句:
alter table 表名
change ......;
change ......;

Ajouter une contrainte de clé étrangère: pour vérifier la validité des données (mot - clé: clé étrangère)

alter table 表名1 add foreign key (字段1) references 表名2(字段2);  --给 表1 的 字段1 添加外键,引用的是 表2 的 字段2
alter table goods add foreign key (cate_id) references goods_cates(id);

Remarque: Lorsque vous ajoutez une clé étrangère, retirez d'abord les données non valides

 

Créer une table « liste Marque »

Vous pouvez créer se référer à la liste ci-dessus « Catégories », d'abord créer la table, puis insérez les données.

Vous pouvez également créer une table de données en créer ... et sélectionnez les enregistrements d'écriture en même temps, en une seule étape

-- select brand_name from goods group by brand_name;

-- 在创建数据表的时候一起插入数据
-- 注意: 需要对brand_name 用as起别名,否则name字段就没有值(查到的字段要与插入的字段同名)
create table goods_brands (
    id int unsigned primary key auto_increment,
    name varchar(40) not null) select brand_name as name from goods group by brand_name;

-- 看一下结果
select * from goods_brands;
+----+--------+
| id | name   |
+----+--------+
|  1 | ibm    |
|  2 | 华硕   |
|  3 | 宏碁   |
|  4 | 惠普   |
|  5 | 戴尔   |
|  6 | 索尼   |
|  7 | 联想   |
|  8 | 苹果   |
|  9 | 雷神   |
+----+--------+

synchronisation des données

table de données de marchandises est mis à jour par les goods_brands de table de données

update goods as g inner join goods_brands as b on g.brand_name=b.name set g.brand_name=b.id;

Structure de table modifiée de l'instruction alter table par

alter table goods  
change brand_name brand_id int unsigned not null;

Ajouter une contrainte de clé étrangère: pour vérifier la validité des données (mot - clé: clé étrangère)

alter table 表名1 add foreign key (字段1) references 表名2(字段2);  --给 表1 的 字段1 添加外键,引用的是 表2 的 字段2
alter table goods add foreign key (brand_id) references goods_brands(id);

attaché :

  • Comment définissez-vous une contrainte de clé étrangère lors de la création de la table de données?

  • Note: les marchandises du type cate_id doivent être goods_cates id table et le type d'accord

create table goods(
    id int primary key auto_increment not null,
    name varchar(40) default '',
    price decimal(5,2),
    cate_id int unsigned,
    brand_id int unsigned,
    is_show bit default 1,
    is_saleoff bit default 0,
    foreign key(cate_id) references goods_cates(id),
    foreign key(brand_id) references goods_brands(id)
);
  • Comment annuler la contrainte de clé étrangère
-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table goods;
-- 获取名称之后就可以根据名称来删除外键约束
alter table goods drop foreign key 外键名称;

(查询外键名:show create table 表名;查询结果中CONSTRAINT后面的 既是外键名称)
  • Dans le développement réel, en utilisant rarement la contrainte de clé étrangère, réduira considérablement l'efficacité des mises à jour de table

 

 

opération MySQL 3. python

 

3.1. Procédé de fonctionnement Python MySQL

 

(1) ubuntu installer le logiciel MySQL

Sudo apt-get install le nom du logiciel

 

(2) Module Installation pymysql

  • Disponibilité: PIP3 installer pymysql  ou  sudo installer PIP3 pymysql 
  • Lorsqu'aucun réseau: Télécharger bonne .whl fichier correspondant, dans un terminal exécuter: PIP installer .whl nom de fichier 

 

(3) dans le module

Introduit les fichiers py module pymysql

import pymysql               # python3
from pymysql import *        # python3

import MySQLdb               # python2

 

(4) l' écoulement de base du fonctionnement de MySQL python:

  • Créer un objet de connexion
  • Créer un objets curseur du curseur
  • Manipulation des données
  • objets de connexion à proximité, objets du curseur

 

(5) objet de connexion et l'introduction de l'objet curseur

objet de connexion:

  • Pour établir une connexion avec la base de données

  • Créer un objet: appeler la méthode connect ()

conn=connect(参数列表)
  • hôte Paramètres: connexion hôte MySQL, si l'unité est « localhost »
  • Port Paramètres: connexions port hôte MySQL, par défaut est 3306
  • Nom de la base de données: base de données de paramètres
  • Paramètres utilisateur: connexions nom d'utilisateur
  • Mot de passe Paramètres: connexion par mot de passe
  • Paramètres charset: codant pour des communications en utilisant UTF8 recommandé

Méthodes d'objets

  • close () ferme la connexion
  • commit () soumis
  • curseur () retourne l'objet curseur pour exécuter instruction SQL et obtenir les résultats

 

objet curseur:

  • Pour exécuter des instructions SQL, des déclarations plus haute fréquence d'utilisation pour sélectionner, insérer, mettre à jour, supprimer
  • Obtient l'objet curseur: pour appeler la méthode du curseur de l'objet de connexion ()
cs1=conn.cursor()

Méthodes d'objets

  • close () Ferme
  • exécuter (opération [paramètres]) l'instruction est exécutée, retourne le nombre de lignes affectées, principalement pour effectuer insertion, mise à jour, les déclarations de suppression peuvent être exécutées de créer, modifier, supprimer ces phrases
  • soit fetchOne () cas d'une requête, le jeu de résultats de requête l' acquisition d' une première ligne de données, renvoie un tuple
  • ou fetchall () est exécutée requête, le jeu de résultats acquis toutes les lignes, une ligne composée d'un tuple, ces éléments est assemblé dans un tuple de retour ( retour tuples Ganso )
  • fetchmany (paramètre) est exécutée requête, obtenir la ligne spécifiée de l'ensemble de résultats (spécifié par les paramètres), constituent une ligne de tuple, et ensuite l' assemblage de ces éléments dans un des retours de tuple

Propriétés de l'objet

  • rowcount attribut lecture seule de la dernière exécution () le nombre de lignes affectées après l'exécution
  • connexion pour obtenir l'objet de connexion en cours

 

3.2. Les opérations de requête de base

interrogation des données

Après avoir créé l'objet de connexion et le curseur objet curseur, pour exécuter une instruction SQL appelle objet curseur de l'exécution , les Execute renvoie le nombre de lignes (vérifier) est entrée en vigueur. Après l' exécution d' une requête, par .fetchone objet curseur ()  ou  objet curseur .fetchmany (nombre) (non écrit de prendre un certain nombre de défaut) ou  objet curseur .fetchall ()  pour prendre des données. (Soit fetchOne retourné tuples, fetchall fetchmany et progénitrices de neurones de retour Ganso)

from pymysql import *

def main():
    # 创建Connection连接(必须)
    conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
    # 获得Cursor对象(必须)
    cs1 = conn.cursor()

    # 执行select语句,并返回受影响的行数:查询一条数据 (通过调用Cursor对象的execute来执行SQL语句,execute返回生效的行数)
    count = cs1.execute('select id,name from goods where id>=4')
    # 打印受影响的行数
    print("查询到%d条数据:" % count)

    # 一行行的获取查询结果-----
    for i in range(count):
        # 获取查询的结果
        result = cs1.fetchone()
        # 打印查询的结果
        print(result)
        # 获取查询的结果

    # 一次获取查询结果的所有行----
    # result = cs1.fetchall()
    # print(result)
    

    # 关闭Cursor对象
    cs1.close()
    conn.close()

if __name__ == '__main__':
    main()

 

 

Case : Jingdong Mall requête

Sous forme de paramètres facultatifs, fournissant une requête pour tous les produits, la classification des requêtes 2, 3 requêtes classification de la marque.

idées :

  • D'une manière orientée objet, chaque méthode mettant en oeuvre une fonction d'interrogation;
  • connexion de base de données et la déconnexion sans écrit dans chaque méthode de fonction d'interrogation, peuvent être connectés à la méthode __init__, __ del__ procédé pour fermer la connexion.
  • De plus, pour parvenir à la requête peut également être utilisé comme méthode pour l'appel.
     
from pymysql import connect


class JD(object):
    def __init__(self):
        
        # 创建Connection连接
        self.conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
        # 获得Cursor对象
        self.cursor = self.conn.cursor()


    def __del__(self):
        
        # 关闭cursor对象
        self.cursor.close()   # 别漏了self.
        # 关闭Connection对象
        self.conn.close()

    def execute_sql(self,sql):
        self.cursor.execute(sql)
        for temp in self.cursor.fetchall():
            print(temp)

    def show_all_items(self):
        """"显示所有的商品"""
        sql = "select * from goods;"
        self.execute_sql(sql)

    def show_cates(self):
        sql = "select name from goods_cates;"
        self.execute_sql(sql)

    def show_brands(self):
        sql = "select name from goods_brands;"
        self.execute_sql(sql)


    # 该方法不需要实例对象也不需要类对象,可以用静态方法实现
    @staticmethod
    def print_menu():
        print("-----京东------")
        print("1:所有的商品")
        print("2:所有的商品分类")
        print("3:所有的商品品牌分类")
        return input("请输入功能对应的序号:")
        
    def run(self):
        while True:
            num = self.print_menu()
            if num == "1":
                # 查询所有商品
                self.show_all_items()
            elif num == "2":
                # 查询分类
                self.show_cates()
            elif num == "3":
                # 查询品牌分类
                self.show_brands()
            else:
                print("输入有误,请重新输入...")


def main():
    # 1. 创建一个京东商城对象
    jd = JD()

    # 2. 调用这个对象的run方法,让其运行
    jd.run()


if __name__ == "__main__":
    main()

 

3.3. Opérations de base CRUD

  • Par curseur ajouts et suppressions traitées par l'objet de connexion ne commettent. Seulement après engagement, les ajouts et les suppressions à la peine de prendre effet;
  • Avant de ne pas commettre, peut être annulé lorsque exécuter en reliant des objets .rollback ();
  • Les ajouts et les suppressions de modification des données, la différence de python est différent instruction SQL

Cas : Ajout d' une marque (augmentation)

from pymysql import connect


class JD(object):
    def __init__(self):
        
        # 创建Connection连接
        self.conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
        # 获得Cursor对象
        self.cursor = self.conn.cursor()

    def __del__(self):
        
        # 关闭cursor对象
        self.cursor.close()   # 别漏了self.
        # 关闭Connection对象
        self.conn.close()

    def execute_sql(self,sql):
        self.cursor.execute(sql)
        for temp in self.cursor.fetchall():
            print(temp)

    def show_all_items(self):
        """"显示所有的商品"""
        sql = "select * from goods;"
        self.execute_sql(sql)

    def show_cates(self):
        sql = "select name from goods_cates;"
        self.execute_sql(sql)

    def show_brands(self):
        sql = "select name from goods_brands;"
        self.execute_sql(sql)

    def add_brands(self):
        item_name = input("输入新品牌的名字:")
        sql = '''insert into goods_brands (name) values("%s")''' % item_name  # 可用三引号防止引号冲突
        self.cursor.execute(sql)
        self.conn.commit()

    # 该方法不需要实例对象也不需要类对象,可以用静态方法实现
    @staticmethod
    def print_menu():
        print("-----京东------")
        print("1:所有的商品")
        print("2:所有的商品分类")
        print("3:所有的商品品牌分类")
        print("4:添加一个品牌分类")
        return input("请输入功能对应的序号:")
        
    def run(self):
        while True:
            num = self.print_menu()
            if num == "1":
                # 查询所有商品
                self.show_all_items()
            elif num == "2":
                # 查询分类
                self.show_cates()
            elif num == "3":
                # 查询品牌分类
                self.show_brands()
            elif num == "4":
                # 添加一个品牌分类
                self.add_brands()
            else:
                print("输入有误,请重新输入...")


def main():
    # 1. 创建一个京东商城对象
    jd = JD()

    # 2. 调用这个对象的run方法,让其运行
    jd.run()


if __name__ == "__main__":
    main()

 

3.4. Paramétrisation

  • déclaration Parametric sql, peut effectivement empêcher l'injection sql
  • Remarque: Contrairement à la chaîne mise en forme python ici, tous les% s espace réservé

Dans un cas, pour ajouter des fonctionnalités à la requête de 5 marchandise par son nom.

from pymysql import connect


class JD(object):
    def __init__(self):
        # 创建Connection连接
        self.conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')
        # 获得Cursor对象
        self.cursor = self.conn.cursor()

    def __del__(self):
        # 关闭cursor对象
        self.cursor.close()   # 别漏了self.
        # 关闭Connection对象
        self.conn.close()

    def execute_sql(self,sql):
        self.cursor.execute(sql)
        for temp in self.cursor.fetchall():
            print(temp)

    def show_all_items(self):
        """"显示所有的商品"""
        sql = "select * from goods;"
        self.execute_sql(sql)

    def show_cates(self):
        sql = "select name from goods_cates;"
        self.execute_sql(sql)

    def show_brands(self):
        sql = "select name from goods_brands;"
        self.execute_sql(sql)

    def add_brands(self):
        item_name = input("输入新品牌的名字:")
        sql = '''insert into goods_brands (name) values("%s")''' % item_name  # 用三引号防止引号冲突
        self.cursor.execute(sql)
        self.conn.commit()

    def get_info_by_name(self):
        find_name = input("请输入要查询的商品名字:")
	
        # # 非安全的方式
        # # 输入 ' or 1=1 or '   (引号也要输入) 就会被sql注入
        # sql="""select * from goods where name='%s';""" % find_name
        # print("------>%s<------" % sql)
        # self.execute_sql(sql)

        # 相对安全的方式
        # 构造参数列表
        sql = "select * from goods where name=%s"
        self.cursor.execute(sql, [find_name])	# [find_name]: 输入的值存到列表中
        print(self.cursor.fetchall())
        # 注意:
   	# 如果要是有多个参数,需要进行参数化
    	# 那么params = [数值1, 数值2....],此时sql语句中有多个%s即可
	
    # 该方法不需要实例对象也不需要类对象,可以用静态方法实现
    @staticmethod
    def print_menu():
        print("-----京东------")
        print("1:所有的商品")
        print("2:所有的商品分类")
        print("3:所有的商品品牌分类")
        print("4:添加一个品牌分类")
        print("5:根据名字查询一个商品")
        return input("请输入功能对应的序号:")
        
    def run(self):
        while True:
            num = self.print_menu()
            if num == "1":
                # 查询所有商品
                self.show_all_items()
            elif num == "2":
                # 查询分类
                self.show_cates()
            elif num == "3":
                # 查询品牌分类
                self.show_brands()
            elif num == "4":
                # 添加一个品牌分类
                self.add_brands()
            elif num == "5":
                # 根据名字查询商品
                self.get_info_by_name()
            else:
                print("输入有误,请重新输入...")


def main():
    # 1. 创建一个京东商城对象
    jd = JD()

    # 2. 调用这个对象的run方法,让其运行
    jd.run()


if __name__ == "__main__":
    main()

L'exemple ci-dessus, si la requête de code est:

find_name = input("请输入要查询的商品名字:")
sql="""select * from goods where name='%s';""" % find_name
print("------>%s<------" % sql)
  • Si l'entrée utilisateur  . 'Ou = 1. 1 ou' 1   , l'instruction SQL phrase serait:  SELECT * d' où le nom marchandises = '' ou = 1. 1 ou. » 1' ;.   . 1 = 1 est toujours mis en place, il formera une injection sql, toutes les données sont pas de sécurité, sera interrogé.
  • moyen sûr pour construire la liste des arguments (voir la mise en œuvre du code), utiliser pour exécuter chaîne d'instruction sql épissage.
  • Le présent mode de réalisation est un seul paramètre, REMARQUE: S'il y avait une pluralité de paramètres, le paramétrage est requis, params = alors [valeur 1, valeur 2 ....], lorsqu'une pluralité de l'instruction sql% s .

 

penser

Sur la base de la base de données ci-dessus, ajoutez la table client [client] (id, nom, adr, tel), bon de commande [commandes] (......), [Table Détails de la commande order_detail] (...... );

Basé sur le programme ci-dessus, le registre d'ajouter, connectez-vous, placez une fonction de commande.

Créer une table « client »

create table customer(
    id int unsigned auto_increment primary key not null,
    name varchar(30) not null,
    addr varchar(100),
    tel varchar(11) not null
);

Création de la table « Commandes »

create table orders(
    id int unsigned auto_increment primary key not null,
    order_date_time datetime not null,
    customer_id int unsigned,
    foreign key(customer_id) references customer(id)
);

Création de la table « Détails de la commande »

create table order_detail(
    id int unsigned auto_increment primary key not null,
    order_id int unsigned not null,
    goods_id int unsigned not null,
    quantity tinyint unsigned not null,
    foreign key(order_id) references orders(id),
    foreign key(goods_id) references goods(id)
);

......

 

 

------fin-------

Publié 50 articles originaux · a gagné les éloges 10 · vues 6608

Je suppose que tu aimes

Origine blog.csdn.net/qq_23996069/article/details/104420591
conseillé
Classement