Python之路第十二天,高級(5)-Python操做Mysql,SqlAlchemy

Mysql基礎

1、安裝

Windows:html

1.下載
http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.31-winx64.zip

2.解壓
將壓縮包解壓到你想要安裝的位置,例如個人解壓到C:\Program Files\mysql-5.6.31-winx64

3.配置環境變量
右擊個人電腦-->屬性-->高級系統設置-->高級-->環境變量-->系統變量-->找到Path變量-->編輯
在最後添加 ;C:\Program Files\mysql-5.6.31-winx64\bin 將bin目錄添加到環境變量裏面去

4. 修改配置文件
將C:\Program Files\mysql-5.6.31-winx64\my.default.int 更名爲my.ini,並打開此文件修改一些配置
[mysqld] 
basedir= C:\Program Files\mysql-5.6.31-winx64(mysql所在目錄) 
datadir= C:\Program Files\mysql-5.6.31-winx64\data (數據目錄)

5. 將Mysql註冊爲服務
打開CMD(必須以管理員身份運行),而後必須進入mysql的bin目錄下執行 mysqld.exe -install
執行成功會提示Service successfully installed

6.啓動Mysql
在CMD裏執行net start mysql
執行mysql啓動成功,則說明就可使用mysql了

7.進入mysql
在CMD裏執行 mysql,成功進入mysql命令行

Linux:python

CentOS: 
[root@localhost ~]# yum install mysql-server

Ubuntu:
[python@localhost ~]$ sudo apt-get install mysql-server

2、SQL基礎

1. 顯示可用的數據庫mysql

mysql> show databases;

2. 使用數據庫sql

mysql> use test;

3. 顯示數據庫中的全部表數據庫

mysql> show tables;

4. 用戶管理編程

建立用戶:
mysql> create user '用戶名'@'IP地址' identified by '密碼';

刪除用戶:
mysql> drop user '用戶名'@'IP地址';

修改用戶:
mysql> rename user '用戶名'@'IP地址' to '新用戶名'@'IP地址';

修改密碼:
mysql> set password for '用戶名'@'IP地址' = password('新密碼');

5. 受權管理服務器

show grants for '用戶'@'IP地址';                  -- 查看權限
grant  權限 on 數據庫.表 to   '用戶'@'IP地址'      -- 受權
grant  權限 on 數據庫.表 to   '用戶'@'IP地址' identified by '密碼';  -- 受權並建立用戶(建立用戶經常使用這條命令)
revoke 權限 on 數據庫.表 from '用戶'@'IP地址'      -- 取消權限

關於權限:session

all privileges  除grant外的全部權限
            select          僅查權限
            select,insert   查和插入權限
            ...
            usage                   無訪問權限
            alter                   使用alter table
            alter routine           使用alter procedure和drop procedure
            create                  使用create table
            create routine          使用create procedure
            create temporary tables 使用create temporary tables
            create user             使用create user、drop user、rename user和revoke  all privileges
            create view             使用create view
            delete                  使用delete
            drop                    使用drop table
            execute                 使用call和存儲過程
            file                    使用select into outfile 和 load data infile
            grant option            使用grant 和 revoke
            index                   使用index
            insert                  使用insert
            lock tables             使用lock table
            process                 使用show full processlist
            select                  使用select
            show databases          使用show databases
            show view               使用show view
            update                  使用update
            reload                  使用flush
            shutdown                使用mysqladmin shutdown(關閉MySQL)
            super                   使用change master、kill、logs、purge、master和set global。還容許mysqladmin調試登錄
            replication client      服務器位置的訪問
            replication slave       由複製從屬使用

關於數據庫oracle

對於目標數據庫以及內部其餘:
            數據庫名.*           數據庫中的全部表
            數據庫名.表          指定數據庫中的某張表
            數據庫名.存儲過程    指定數據庫中的存儲過程
            *.*                  全部數據庫

關於用戶名框架

在Mysql裏用戶名@IP地址纔是真正的用戶名,缺一不可

用戶名@IP地址        用戶只能在改IP下才能訪問
用戶名@192.168.1.%   用戶只能在改IP段下才能訪問(通配符%表示任意)
用戶名@%             用戶能夠再任意IP下訪問(默認IP地址爲%)

舉例

# 將db1庫裏的tb1表的全部權限都受權給'用戶名'@'IP'
mysql> grant all privileges on db1.tb1 TO '用戶名'@'IP';

# 將db1庫裏的全部表的select權限受權給'用戶名'@'IP';
mysql> grant select on db1.* TO '用戶名'@'IP'

# 將全部庫全部表的select,insert權限受權給'用戶名'@'IP';
mysql> grant select,insert on *.* TO '用戶名'@'IP'

# 取消'用戶名'@'IP'對db1庫b1表的select權限
mysql> revoke select on db1.tb1 from '用戶名'@'IP';

建立數據庫

mysql> create database db1 default charset utf8;

建立表

create table 表名(
    列名  類型  是否能夠爲空,
    列名  類型  是否能夠爲空
)

是否爲空:

是否可空,null表示空,非字符串
          not null   - 不可空
          null       - 可空

默認值:

默認值,建立列時能夠指定默認值,當插入數據時若是未主動設置,則自動添加默認值
            create table tb1(
                nid int not null defalut 0,
                num int not null
            )

主鍵:

主鍵,一種特殊的惟一索引,不容許有空值,若是主鍵使用單個列,則它的值必須惟一,若是是多列,則其組合必須惟一。
            create table tb1(
                nid int not null auto_increment primary key,
                num int null
            )
            或
            create table tb1(
                nid int not null,
                num int not null,
                primary key(nid,num)
            )

外鍵:

外鍵,一個特殊的索引,只能是指定內容
            creat table color(
                nid int not null primary key,
                name char(16) not null
            )

            create table fruit(
                nid int not null primary key,
                smt char(32) null ,
                color_id int not null,
                constraint fk_cc foreign key (color_id) references color(nid)
            )

刪除表

drop table 表名

清空表

delete from 表名
truncate table 表名

修改表

添加列:alter table 表名 add 列名 類型
刪除列:alter table 表名 drop column 列名
修改列:
        alter table 表名 modify column 列名 類型;  -- 類型
        alter table 表名 change 原列名 新列名 類型; -- 列名,類型
 
添加主鍵:
        alter table 表名 add primary key(列名);
刪除主鍵:
        alter table 表名 drop primary key;
        alter table 表名  modify  列名 int, drop primary key;
 
添加外鍵:
        alter table 從表 add constraint 外鍵名稱(形如:FK_從表_主表) foreign key 從表(外鍵字段) references 主表(主鍵字段);
刪除外鍵:
        alter table 表名 drop foreign key 外鍵名稱
 
修改默認值:
        ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;

刪除默認值:
        ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;

Mysql數據庫基本操做:

insert into 表 (列名,列名...) values (值,值,值...)
insert into 表 (列名,列名...) values (值,值,值...),(值,值,值...)
insert into 表 (列名,列名...) select (列名,列名...) from 表

delete from 表
delete from 表 where id=1 and name='alex'

update 表 set name = 'alex' where id>1

select * from 表;
select * from 表 where id > 1;
select nid,name,gender as gg from 表 where id > 1;

其它

條件:
     select * from 表 where id > 1 and name != 'alex' and num = 12;
     select * from 表 where id between 5 and 16;
     select * from 表 where id in (11,22,33)
     select * from 表 where id not in (11,22,33)
     select * from 表 where id in (select nid from 表)

通配符:
     select * from 表 where name like 'ale%'  - ale開頭的全部(多個字符串)
     select * from 表 where name like 'ale_'  - ale開頭的全部(一個字符)

限制:
     select * from 表 limit 5;            - 前5行
     select * from 表 limit 4,5;          - 從第4行開始的5行
     select * from 表 limit 5 offset 4    - 從第4行開始的5行

排序:
     select * from 表 order by 列 asc              - 根據 「列」 從小到大排列
     select * from 表 order by 列 desc             - 根據 「列」 從大到小排列
     select * from 表 order by 列1 desc,列2 asc    - 根據 「列1」 從大到小排列,若是相同則按列2從小到大排序

分組:
     select num from 表 group by num
     select num,nid from 表 group by num,nid
     select num,nid from 表  where nid > 10 group by num,nid order nid desc
     select num,nid,count(*),sum(score),max(score),min(score) from 表 group by num,nid
     select num from 表 group by num having max(id) > 10

     特別的:group by 必須在where以後,order by以前

連表:
    無對應關係則不顯示
    select A.num, A.name, B.name
    from A,B
    Where A.nid = B.nid

    無對應關係則不顯示
    select A.num, A.name, B.name
    from A inner join B
    on A.nid = B.nid

    A表全部顯示,若是B中無對應關係,則值爲null
    select A.num, A.name, B.name
    from A left join B
    on A.nid = B.nid

    B表全部顯示,若是B中無對應關係,則值爲null
    select A.num, A.name, B.name
    from A right join B
    on A.nid = B.nid

組合:
    組合,自動處理重合
    select nickname from A union select name from B

    組合,不處理重合
    select nickname from A union all select name from B

pymsql MySQLdb

pymsql是Python中操做MySQL的模塊,其使用方法和MySQLdb幾乎相同。pymysql用在Python3.x中,MySQLdb用在Python2.x中

1、安裝

pip3 install pymsql

2、使用

import pymysql
 
# 建立鏈接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
# 建立遊標
cursor = conn.cursor()
 
# 執行SQL,並返回收影響行數
effect_row = cursor.execute("update hosts set host = '1.1.1.2'")
 
# 執行SQL,並返回受影響行數
#effect_row = cursor.execute("update hosts set host = '1.1.1.2' where nid > %s", (1,))
 
# 執行SQL,並返回受影響行數
#effect_row = cursor.executemany("insert into hosts(host,color_id)values(%s,%s)", [("1.1.1.11",1),("1.1.1.11",2)])
 
 
# 提交,否則沒法保存新建或者修改的數據
conn.commit()
 
# 關閉遊標
cursor.close()
# 關閉鏈接
conn.close()

獲取最新插入數據自增ID

import pymysql
 
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
cursor = conn.cursor()
cursor.executemany("insert into hosts(host,color_id)values(%s,%s)", [("1.1.1.11",1),("1.1.1.11",2)])
conn.commit()
cursor.close()
conn.close()
 
# 獲取最新自增ID
new_id = cursor.lastrowid

獲取查詢數據

import pymysql
 
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
cursor = conn.cursor()
cursor.execute("select * from hosts")
 
# 獲取第一行數據
row_1 = cursor.fetchone()
 
# 獲取前n行數據
# row_2 = cursor.fetchmany(3)

# 獲取全部數據
# row_3 = cursor.fetchall()
 
cursor.close()
conn.close()

注:在fetch數據時按照順序進行,可使用cursor.scroll(num,mode)來移動遊標位置,如:

cursor.scroll(1,mode='relative')  # 相對當前位置移動
cursor.scroll(2,mode='absolute')  # 相對絕對位置移動

fetch數據類型

  關於默認獲取的數據是元組類型,若是想要或者字典類型的數據,即:

import pymysql
 
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
 
# 遊標設置爲字典類型
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
r = cursor.execute("call p1()")
 
result = cursor.fetchone()
 
cursor.close()
conn.close()

SQLAlchemy

SQLAlchemy是Python編程語言下的一款ORM框架,該框架創建在數據庫API之上,使用關係對象映射進行數據庫操做,簡言之即是:將對象轉換成SQL,而後使用數據API執行SQL並獲取執行結果。

SQLAlchemy自己沒法操做數據庫,其必須以來pymsql等第三方插件,Dialect用於和數據API進行交流,根據配置文件的不一樣調用不一樣的數據庫API,從而實現對數據庫的操做,如:

MySQL-Python
    mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
  
pymysql
    mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
  
MySQL-Connector
    mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
  
cx_Oracle
    oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]

更多請點擊: http://docs.sqlalchemy.org/en/latest/dialects/index.html

底層處理

使用 Engine/ConnectionPooling/Dialect 進行數據庫操做,Engine使用ConnectionPooling鏈接數據庫,而後再經過Dialect執行SQL語句。

from sqlalchemy import create_engine
 
 
engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)
 
# 執行SQL
# cur = engine.execute(
#     "INSERT INTO hosts (host, color_id) VALUES ('1.1.1.22', 3)"
# )
 
# 新插入行自增ID
# cur.lastrowid
 
# 執行SQL
# cur = engine.execute(
#     "INSERT INTO hosts (host, color_id) VALUES(%s, %s)",[('1.1.1.22', 3),('1.1.1.221', 3),]
# )
 
 
# 執行SQL
# cur = engine.execute(
#     "INSERT INTO hosts (host, color_id) VALUES (%(host)s, %(color_id)s)",
#     host='1.1.1.99', color_id=3
# )
 
# 執行SQL
# cur = engine.execute('select * from hosts')
# 獲取第一行數據
# cur.fetchone()
# 獲取第n行數據
# cur.fetchmany(3)
# 獲取全部數據
# cur.fetchall()

ORM功能使用

使用 ORM/Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 全部組件對數據進行操做。根據類建立對象,對象轉換成SQL,執行SQL。

1. 建立表
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)

Base = declarative_base()

# 建立單表
class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    extra = Column(String(16))

    __table_args__ = (
    UniqueConstraint('id', 'name', name='uix_id_name'),
        Index('ix_id_name', 'name', 'extra'),
    )


# 一對多
class Favor(Base):
    __tablename__ = 'favor'
    nid = Column(Integer, primary_key=True)
    caption = Column(String(50), default='red', unique=True)


class Person(Base):
    __tablename__ = 'person'
    nid = Column(Integer, primary_key=True)
    name = Column(String(32), index=True, nullable=True)
    favor_id = Column(Integer, ForeignKey("favor.nid"))


# 多對多
class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)
    port = Column(Integer, default=22)


class Server(Base):
    __tablename__ = 'server'

    id = Column(Integer, primary_key=True, autoincrement=True)
    hostname = Column(String(64), unique=True, nullable=False)


class ServerToGroup(Base):
    __tablename__ = 'servertogroup'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    server_id = Column(Integer, ForeignKey('server.id'))
    group_id = Column(Integer, ForeignKey('group.id'))


def init_db():
    Base.metadata.create_all(engine)


def drop_db():
    Base.metadata.drop_all(engine)

2. 操做表

表結構加鏈接數據庫

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)

Base = declarative_base()

# 建立單表
class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    extra = Column(String(16))

    __table_args__ = (
    UniqueConstraint('id', 'name', name='uix_id_name'),
        Index('ix_id_name', 'name', 'extra'),
    )

    def __repr__(self):
        return "%s-%s" %(self.id, self.name)

# 一對多
class Favor(Base):
    __tablename__ = 'favor'
    nid = Column(Integer, primary_key=True)
    caption = Column(String(50), default='red', unique=True)

    def __repr__(self):
        return "%s-%s" %(self.nid, self.caption)

class Person(Base):
    __tablename__ = 'person'
    nid = Column(Integer, primary_key=True)
    name = Column(String(32), index=True, nullable=True)
    favor_id = Column(Integer, ForeignKey("favor.nid"))
    # 與生成表結構無關,僅用於查詢方便
    favor = relationship("Favor", backref='pers')

# 多對多
class ServerToGroup(Base):
    __tablename__ = 'servertogroup'
    nid = Column(Integer, primary_key=True, autoincrement=True)
    server_id = Column(Integer, ForeignKey('server.id'))
    group_id = Column(Integer, ForeignKey('group.id'))
    group = relationship("Group", backref='s2g')
    server = relationship("Server", backref='s2g')

class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)
    port = Column(Integer, default=22)
    # group = relationship('Group',secondary=ServerToGroup,backref='host_list')


class Server(Base):
    __tablename__ = 'server'

    id = Column(Integer, primary_key=True, autoincrement=True)
    hostname = Column(String(64), unique=True, nullable=False)




def init_db():
    Base.metadata.create_all(engine)


def drop_db():
    Base.metadata.drop_all(engine)


Session = sessionmaker(bind=engine)
session = Session()

obj = Users(name="alex0", extra='sb')
session.add(obj)
session.add_all([
    Users(name="alex1", extra='sb'),
    Users(name="alex2", extra='sb'),
])
session.commit()

session.query(Users).filter(Users.id > 2).delete()
session.commit()

session.query(Users).filter(Users.id > 2).update({"name" : "099"})
session.query(Users).filter(Users.id > 2).update({Users.name: Users.name + "099"}, synchronize_session=False)
session.query(Users).filter(Users.id > 2).update({"num": Users.num + 1}, synchronize_session="evaluate")
session.commit()

ret = session.query(Users).all()
ret = session.query(Users.name, Users.extra).all()
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter_by(name='alex').first()

其它

# 條件
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()
ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
from sqlalchemy import and_, or_
ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
ret = session.query(Users).filter(
    or_(
        Users.id < 2,
        and_(Users.name == 'eric', Users.id > 3),
        Users.extra != ""
    )).all()


# 通配符
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all()

# 限制
ret = session.query(Users)[1:2]

# 排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()

# 分組
from sqlalchemy.sql import func

ret = session.query(Users).group_by(Users.extra).all()
ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id)).group_by(Users.name).all()

ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()

# 連表

ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()

ret = session.query(Person).join(Favor).all()

ret = session.query(Person).join(Favor, isouter=True).all()


# 組合
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all()

q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all()
相關文章
相關標籤/搜索