1. 程式人生 > 其它 >(轉)python之sqlalchemy詳解

(轉)python之sqlalchemy詳解

原文:https://zhuanlan.zhihu.com/p/71134861

ps = session.query(Person).first()
print(ps)
# 3、修改制定行資料
person = session.query(Person).first()
print(person)
# 修改表資料,物件.屬性 = '   '
person.name = 'hahaha'
# 別忘記要提交哦~
session.commit()
# 4、刪除表資料
person = session.query(Person).get(3)
print(person)
session.delete(person)
session.commit()

Column常用資料型別

常用的資料型別,一共是有11個。

注:在SQLAlchemy中不存在double資料型別,使用DECIMAL型別替代

讓我們來分別看下這11個數據型別都有哪些?

  1. Integer:整型,對映到資料庫中是int型別。
  2. Float:浮點型別,對映到資料庫中是float型別。他佔據的32位。
    浮點型別,有可能會造成精度丟失,特別是在money方面,不可原諒。
  3. Double(SQLAlchemy中沒有,代替品為DECIMAL):雙精度浮點型別,對映到資料庫中是double型別,佔據64位
  4. String:可變字元型別,對映到資料庫中是varchar型別.
  5. Boolean:布林型別,對映到資料庫中的是tinyint型別。
  6. DECIMAL:定點型別。是專門為了解決浮點型別精度丟失的問題的。在儲存money相關的欄位的時候建議大家都使用這個資料型別。並且這個型別使用的時候需要傳遞兩個引數,第一個引數是用來標記這個欄位總能能儲存多少個數字,第二個引數表示小數點後有多少位。
  7. Enum:列舉型別。指定某個欄位只能是列舉中指定的幾個值,不能為其他值。在ORM模型中,使用Enum來作為列舉。
  8. Date:儲存時間,只能儲存年月日。對映到資料庫中是date型別。在Python程式碼中,可以使用datetime.date來指定。
  9. DateTime:儲存時間,可以儲存年月日時分秒毫秒等。對映到資料庫中也是datetime型別。在Python程式碼中,可以使用datetime.datetime
    來指定。
  10. Time:儲存時間,可以儲存時分秒。對映到資料庫中也是time型別。在Python程式碼中,可以使用datetime.time來指定
    ps:注意區分Date/DateTime/Time的儲存資訊!!!
  11. Text:儲存長字串。一般可以儲存6W多個字元
  12. LONGTEXT:長文字型別,對映到資料庫中是longtext型別(不過這個只有mysql有,orcale沒有)

上述就是11個數據型別,因為這裡把不存在的double也新增上了,所以看起來是12個。

下面就讓咱們一起來進行驗證。

程式碼實現

# 依次匯入常用的資料型別
from sqlalchemy import create_engine, Column, Integer, String,Float,DECIMAL,Boolean,Date,DateTime,Time,Text,Enum
# 從sqlalchemy的方言模組dialects匯入mysql專有的LONGTEXT,長文字型別
from sqlalchemy.dialects.mysql import LONGTEXT
# 在python3.x中有enum模組
import enum
#匯入時間了
from datetime import datetime,date,time
# 用`declarative_base`根據`engine`建立一個ORM基類。
from sqlalchemy.ext.declarative import declarative_base
# 引入建立py和資料庫連線的sessionmaker函式
from sqlalchemy.orm import sessionmaker
# 準備連線資料庫基本資訊
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'first_sqlalchemy'
USERNAME = 'root'
PASSWORD = 'root'
DB_URI = 'mysql+pymysql://{username}:{pwd}@{host}:{port}/{db}?charset=utf8' \
    .format(username=USERNAME, pwd=PASSWORD, host=HOSTNAME, port=PORT, db=DATABASE)
# 建立資料庫引擎
engine = create_engine(DB_URI)
Base = declarative_base(engine)
# 需求:常用的資料型別
# 列舉另外一種寫法,匯入enum模組,定義列舉類
class TagEnum(enum.Enum):
    python = "PYTHON"
    flask = 'FLASK'
    django = 'DJANGO'
class News(Base):
    __tablename__ = 'news'
    id = Column(Integer,primary_key=True,autoincrement=True)
    price1 = Column(Float)   # 不過儲存資料時存在精度丟失的問題
    price2 = Column(DECIMAL(10,4))
    title = Column(String(50))
    is_delete = Column(Boolean)
    tag1 = Column(Enum('PYTHON','FLASK','DJANGO'))  # 列舉的常規寫法(推薦)
    tag2 = Column(Enum(TagEnum))  # 另一種寫法
    create_time1 = Column(Date)
    create_time2 = Column(DateTime)
    create_time3 = Column(Time)
    content1 = Column(Text)
    content2 = Column(LONGTEXT)
# 將Base上的ORM類模型對應的資料表都刪除
# Base.metadata.drop_all()
# 建立Base上的ORM類到資料庫中成為表
# Base.metadata.create_all()
# 新增資料到表news中
session = sessionmaker(engine)()
# 注意float出現的精度丟失問題      is_delete,布林型別true:1,false:0
news1 = News(price1=1000.0078,price2=1000.0078,title='測試資料',is_delete=True,tag1="PYTHON",tag2=TagEnum.flask,    create_time1=date(2018,12,12),create_time2=datetime(2019,2,20,12,12,30),create_time3=time(hour=11,minute=12,second=13),content1="hello",content2 ="hello   hi   nihao")
session.add(news1)
session.commit()

Column常用約束引數

在給資料庫表指定key的時候,必然要給它們新增,例如:不可空,位元組長度等等的限制,這就需要約束引數的出場了。常用的約束引數一共有7種

常見約束引數

約束引數描述,功能primary_keyTrue設定某個欄位為主鍵autoincrementTrue設定這個欄位為自動增長的default設定某個欄位的預設值。在發表時間這些欄位上面經常用nullable指定某個欄位是否為空。預設值是True,就是可以為空unique指定某個欄位的值是否唯一。預設是False。onupdate在資料更新的時候會呼叫這個引數指定的值或者函式。在第一次插入這條資料的時候,不會用onupdate的值,只會使用default的值。常用於是update_time欄位(每次更新資料的時候都要更新該欄位值)。name指定ORM模型中某個屬性對映到表中的欄位名。如果不指定,那麼會使用這個屬性的名字來作為欄位名。這個引數也可以當作位置引數,在第1個引數來指定。

程式碼實現

# 注意千萬不能忘記要先建立session物件啊!!
# 需求:sqlalchemy中Column常用的約束引數
class News(Base):
    __tablename__ = 'news'
    id = Column(Integer,primary_key=True,autoincrement=True)
    # 這個Datetime是sqlalchemy中的
    create_time = Column(DateTime,default=datetime.now)
    read_count = Column(Integer,default=11)
    title1 = Column(String(50),name='my_title',nullable=False)
    title2 = Column('my_title22',String(50), nullable=False)# name 屬性的兩種方式
    telephone = Column(String(11),unique=True)
    update_time = Column(DateTime,onupdate=datetime.now,default=datetime.now)#onupdate是在資料更新的時候才會起作用,插入資料時候不起作用
# Base.metadata.drop_all()
# Base.metadata.create_all()
news1 = News(title1 ='hahah',title2 = 'womingsad')
session.add(news1)
#結束之後,必須要提交
session.commit()

Query查詢函式,可以傳遞的引數有哪些?

Query查詢函式傳遞的引數無非就是分為三類,分別是模型名、模型中的屬性、聚合函式,那下面就簡單的說明,

模型名

指定查詢該模型中所有屬性(對應查詢為全表查詢)

模型中的屬性

可以指定只查詢某個模型的其中幾個屬性

聚合函式

聚合函式一共有五個,都被放到了sqlalchemy的func模組中。
  1. func.count:統計行的數量
  2. func.avg:求平均值
  3. func.max:求最大值
  4. func.min:求最小值
  5. func.sum:求和

程式碼實現

# 新增測試資料
for x in range(1,6):
a = News(title = "標題%s"%x,price = random.randint(1,100))
session.add(a)
# 提交
session.commit()
# 三種引數
# 模型名
result = session.query(News).all()  #全表查詢
print(result)
# 模型名的屬性名,返回的列表中的元素是元組型別資料
result = session.query(News.title,News.price).all()
print(result)
# 聚合函式
# 統計行的數量
r = session.query(func.count(News.id)).first()
print(r)
#最大值
r = session.query(func.max(News.price)).first()
print(r)
#最小值
r = session.query(func.min(News.price)).first()
print(r)
#平均值
r = session.query(func.avg(News.price)).first()
print(r)
#求和
r = session.query(func.sum(News.price)).first()
print(r)
技術連結