Python ORM框架 MySQL 安裝及操作

安裝數(shù)據(jù)庫

下載鏈接
安裝免安裝版即可浑此!
下載完后橙垢,我們將 zip 包解壓到相應(yīng)的目錄陵吸,這里我將解壓后的文件夾放在 指定安裝目錄 下。
接下來我們需要配置下 MySQL 的配置文件

打開剛剛解壓的文件夾 指定安裝目錄山林,在該文件夾下創(chuàng)建 my.ini 配置文件志秃,編輯 my.ini 配置以下基本信息:

[client]
# 設(shè)置mysql客戶端默認(rèn)字符集
default-character-set=utf8
 
[mysqld]
# 設(shè)置3306端口
port = 3306
# 設(shè)置mysql的安裝目錄
basedir=你的指定安裝目錄
# 設(shè)置 mysql數(shù)據(jù)庫的數(shù)據(jù)的存放目錄怔球,MySQL 8+ 不需要以下配置,系統(tǒng)自己生成即可浮还,否則有可能報錯
# datadir=C:\\web\\sqldata
# 允許最大連接數(shù)
max_connections=20
# 服務(wù)端使用的字符集默認(rèn)為8比特編碼的latin1字符集
character-set-server=utf8
# 創(chuàng)建新表時將使用的默認(rèn)存儲引擎
default-storage-engine=INNODB

接下來我們來啟動下 MySQL 數(shù)據(jù)庫:

以管理員身份打開 cmd 命令行工具竟坛,切換目錄:

cd 指定安裝目錄

初始化數(shù)據(jù)庫:

mysqld --initialize --console

執(zhí)行完成后,會輸出 root 用戶的初始默認(rèn)密碼,如:

2018-04-20T02:35:05.464644Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: APWCY5ws&hjQ

APWCY5ws&hjQ 就是MySQL的初始密碼(后期可更改)
輸入以下安裝命令:

mysqld install

啟動輸入以下命令即可:

net start mysql

注意: 在 5.7 需要初始化 data 目錄:
cd 指定安裝目錄
mysqld --initialize-insecure
初始化后再運(yùn)行 net start mysql 即可啟動 mysql担汤。

登錄 MySQL

當(dāng) MySQL 服務(wù)已經(jīng)運(yùn)行時, 我們可以通過 MySQL 自帶的客戶端工具登錄到 MySQL 數(shù)據(jù)庫中, 首先打開命令提示符, 輸入以下格式的命名:

mysql -h 主機(jī)名 -u 用戶名 -p

參數(shù)說明:

  • -h : 指定客戶端所要登錄的 MySQL 主機(jī)名, 登錄本機(jī)(localhost 或 127.0.0.1)該參數(shù)可以省略;
  • -u : 登錄的用戶名;
  • -p : 告訴服務(wù)器將會使用一個密碼來登錄, 如果所要登錄的用戶名密碼為空, 可以忽略此選項(xiàng)涎跨。
    如果我們要登錄本機(jī)的 MySQL 數(shù)據(jù)庫,只需要輸入以下命令即可:
mysql -u root -p 密碼

若密碼存在, 輸入密碼登錄, 不存在則直接按回車登錄崭歧。登錄成功后你將會看到 Welcome to the MySQL monitor... 的提示語隅很。
然后命令提示符會一直以 mysq> 加一個閃爍的光標(biāo)等待命令的輸入, 輸入 exit 或 quit 退出登錄。

ORM 框架

安裝所需環(huán)境

$ pip install SQLAlchemy

查看版本

>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.4.15'

登錄數(shù)據(jù)庫
創(chuàng)建庫

create database test_db;

接下來就可以使用框架對數(shù)據(jù)庫進(jìn)行操作了
創(chuàng)建表
通過映射創(chuàng)建表的實(shí)例

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: bo

from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:zaq123@127.0.0.1:3306/test_db?charset=utf8mb4'
engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)
Base = declarative_base()

class TestMysql(Base):
    __tablename__ = 'table_t'
    id = Column(Integer, primary_key=True)
    sku_code = Column(String(49))  #訂單編號
    goods_name = Column(String(100))  #商品名稱

    def __str__(self):
        return f"TestMysql[id:{self.id}, name:{self.name}]"

# 執(zhí)行
Base.metadata.create_all(engine)

如果你執(zhí)行以上程序成功率碾,你會得到,如:

2021-05-16 12:46:26,470 INFO sqlalchemy.engine.Engine SHOW VARIABLES LIKE 'sql_mode'
2021-05-16 12:46:26,470 INFO sqlalchemy.engine.Engine [raw sql] {}
2021-05-16 12:46:26,472 INFO sqlalchemy.engine.Engine SHOW VARIABLES LIKE 'lower_case_table_names'
2021-05-16 12:46:26,472 INFO sqlalchemy.engine.Engine [generated in 0.00013s] {}
2021-05-16 12:46:26,474 INFO sqlalchemy.engine.Engine SELECT DATABASE()
2021-05-16 12:46:26,474 INFO sqlalchemy.engine.Engine [raw sql] {}
2021-05-16 12:46:26,475 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2021-05-16 12:46:26,475 INFO sqlalchemy.engine.Engine SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = %(table_schema)s AND table_name = %(table_name)s
2021-05-16 12:46:26,475 INFO sqlalchemy.engine.Engine [generated in 0.00013s] {'table_schema': 'test_db', 'table_name': 'table_t'}
2021-05-16 12:46:26,477 INFO sqlalchemy.engine.Engine 
CREATE TABLE table_t (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    sku_code VARCHAR(49), 
    goods_name VARCHAR(100), 
    PRIMARY KEY (id)
)


2021-05-16 12:46:26,477 INFO sqlalchemy.engine.Engine [no key 0.00010s] {}
2021-05-16 12:46:26,671 INFO sqlalchemy.engine.Engine COMMIT

首先需要創(chuàng)建引擎叔营,通過 create_engine 方法完成,echo 參數(shù)控制了是否輸出相關(guān)日志所宰,默認(rèn) False

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:zaq123@127.0.0.1:3306/test_db?charset=utf8mb4'\
engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)

接下來需要創(chuàng)建一個映射用的基類 Base审编,所有需要映射表的類都要繼承這個類,才能完成相關(guān)庫的操作歧匈,比如 Book,在 Book 中設(shè)置參數(shù) tablename 代表映射的表名砰嘁,各個字段需要通過 Column 方法來賦值件炉,并設(shè)置相應(yīng)的字段類型

Base = declarative_base()

class TestMysql(Base):
    __tablename__ = 'table_t'
    id = Column(Integer, primary_key=True)
    sku_code = Column(String(49))  #訂單編號
    goods_name = Column(String(100))  #商品名稱

    def __str__(self):
        return f"TestMysql[id:{self.id}, name:{self.name}]"

最后通過基類對所給引擎的子類進(jìn)行映射創(chuàng)建

Base.metadata.create_all(engine)

操作數(shù)據(jù)庫

下面是個增刪改查的例子:

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()

book = Book(name="new book")
session.add(book)
session.commit()
print(book)         # > Book[id:1, name:new book]   查詢數(shù)據(jù)

book = session.query(Book).filter_by(id=1).first()
print(book)         # > Book[id:1, name:new book]   通過id查詢

book.name = "wxnacy"
session.add(book)
session.commit()

print(book)         # > Book[id:1, name:wxnacy]   修改數(shù)據(jù)
session.delete(book)
session.commit()    # 刪除

SQLAlchemy 在操作數(shù)據(jù)庫時需要用到 Session,通過 sessionmaker 方法獲取矮湘,操作過程中最關(guān)鍵的一步就是 commit斟冕,不然是不會同步到庫中的.

查詢操作

filter_by(), filter() 兩個方法提供了很完成的查詢操作,可以滿足平常大多數(shù)查詢操作缅阳,后者的功能更強(qiáng)大一些

# 獲取滿足條件的第一條數(shù)據(jù)
filter_by(name='wxnacy').first()
filter(Book.name=='wxnacy').first()     # filter 的用法稍有不同

# 獲取滿足條件的所有數(shù)據(jù)
filter_by(name='wxnacy').all()

# 獲取滿足條件的所有數(shù)據(jù)的數(shù)量
filter_by(name='wxnacy').count()

# 后續(xù)實(shí)例省去 all(), first(), count() 等

# and 操作
# 我們在 Book 中增加一個 price 價格字段
# where id = 1 and name = 'wxnacy'
filter_by(name='wxnacy', price=12)
filter_by(name='wxnacy').filter_by(price=12)
# only filter
from sqlalchemy import and_
filter(and_(Book.name='wxnacy', Book.price=12))

# in (only filter)
# where id in (1, 2)
filter(Book.id.in_([1, 2]))

# like (only filter)
# where name like '%wxn%'
filter(Book.name.like('%wxn%'))

# not equals (only filter)
# where id != 1
filter(Book.id != 1)

# not in (only filter)
# where id not in (1, 2)
filter(~Book.id.in_([1, 2]))

# or (only filter)
# where id = 1 or name = 'wxnacy'
from sqlalchemy import or_
filter(or_(Book.id == 1, Book.name == 'wxnacy'))

# order
# order by id
filter_by().order_by(Book.id)
# order by id desc
from sqlalchemy import desc
filter_by().order_by(desc(Book.id))
filter_by().order_by(Book.id.desc())
filter_by().order_by('id desc')

# limit
# limit 4
filter_by().limit(4)
order by

排序有三種方式磕蛇,默認(rèn)為正序排列

# select * from book order by id
session.query(Book).order_by(Book.id).all()

# select * from book order by id desc
from sqlalchemy import desc
session.query(Book).order_by(desc(Book.id)).all()
session.query(Book).order_by(Book.id.desc()).all()
session.query(Book).order_by('id desc').all()
group by

分組

# select name, count(name) as c from book group by name
from sqlalchemy import func
session.query(Book.name, func.count(Book.name).label('c')).group_by(Book.name).all()

批量插入

# insert into book (name) values ('wxnacy');
# insert into book (name) values ('wxnacy');
# 1
session.add(Book(name="wxnacy"))
session.add(Book(name="wxnacy"))
session.commit()

# 2
session.add_all([Book(name="wxnacy"), Book(name="wxnacy")])
session.commit()

# insert into book (name) values ('wxnacy'), ('wxnacy');
# 3
items = [dict(name="wxnacy"), dict(name="wxnacy")]
session.execute(Book.__table__.insert(), items)
session.commit()

從結(jié)果上三種方法都可以實(shí)現(xiàn)批量插入的效果,但是從他們生成的 SQL 語句看十办,前兩個種就是重復(fù)執(zhí)行了單條 insert 語句秀撇,第三種則是將批量添加的數(shù)據(jù)整合到一條語句中,從效率上講肯定是推薦第三種方式

既然這么菜
那我走向族?(滑稽)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呵燕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子件相,更是在濱河造成了極大的恐慌再扭,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夜矗,死亡現(xiàn)場離奇詭異泛范,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)紊撕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門罢荡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事柠傍◆锓” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵惧笛,是天一觀的道長从媚。 經(jīng)常有香客問我,道長患整,這世上最難降的妖魔是什么拜效? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮各谚,結(jié)果婚禮上紧憾,老公的妹妹穿的比我還像新娘。我一直安慰自己昌渤,他們只是感情好赴穗,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著膀息,像睡著了一般般眉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上潜支,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天甸赃,我揣著相機(jī)與錄音,去河邊找鬼冗酿。 笑死埠对,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裁替。 我是一名探鬼主播项玛,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弱判!你這毒婦竟也來了稍计?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤裕循,失蹤者是張志新(化名)和其女友劉穎臣嚣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剥哑,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡硅则,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了株婴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怎虫。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡暑认,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出大审,到底是詐尸還是另有隱情蘸际,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布徒扶,位于F島的核電站粮彤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏姜骡。R本人自食惡果不足惜导坟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望圈澈。 院中可真熱鬧惫周,春花似錦、人聲如沸康栈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啥么。三九已至登舞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饥臂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工似踱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留隅熙,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓核芽,卻偏偏與公主長得像囚戚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轧简,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容