欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python 數(shù)據(jù)庫操作 SQLAlchemy的示例代碼

 更新時間:2019年02月18日 16:06:59   作者:keinYe  
這篇文章主要介紹了Python 數(shù)據(jù)庫操作 SQLAlchemy的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

程序在運行過程中所有的的數(shù)據(jù)都存儲在內(nèi)存 (RAM) 中,「RAM 是易失性存儲器,系統(tǒng)掉電后 RAM 中的所有數(shù)據(jù)將全部丟失」。在大多數(shù)情況下我們希望程序運行中產(chǎn)生的數(shù)據(jù)能夠長久的保存,此時我們就需要將數(shù)據(jù)保存到磁盤上,無論是保存到本地磁盤,還是通過網(wǎng)絡(luò)保存到服務(wù)器上,最終都會將數(shù)據(jù)寫入磁盤文件。將數(shù)據(jù)保存在磁盤中我們需要面對一個數(shù)據(jù)格式的問題,此時就需要引入數(shù)據(jù)庫操作。

數(shù)據(jù)庫是專門用于數(shù)據(jù)的集中存儲和查詢的軟件,它便于程序保存和讀取數(shù)據(jù),且能夠通過特定的條件查詢指定的數(shù)據(jù)。

Python 的標準數(shù)據(jù)庫接口為 Python DB-API,它為編程人員提供了完善的數(shù)據(jù)庫應(yīng)用標稱接口。但是使用 Python DB-API 需要開發(fā)人員自行去拼接 SQL,并把 SQL 做成模板。此時全靠編程人員來保證系統(tǒng)的安全性,完全有人來保證系統(tǒng)的安全性,不可避免的會出現(xiàn)錯誤,為了減少人為原因產(chǎn)生的錯誤 ORM 框架應(yīng)運而生。

ORM 即 Object-Relational Mapping,把關(guān)系數(shù)據(jù)庫的表結(jié)構(gòu)映射到對象上面。負責這個轉(zhuǎn)換過程的就是 ORM 框架

Python 中的 ORM 框架主要有 SQLObject、Storm、Django's ORM、peewee、SQLALchemy。每種 ORM 框架都有各自的特點和相應(yīng)的應(yīng)用范圍,本文主要介紹 SALALchemy,若你對其他框架感興趣請自行搜索相關(guān)內(nèi)容。

SQLAlchemy 簡介

SQLAlchemy 是一個功能強大的開源 Python ORM 工具包。它提供了 “一個知名企業(yè)級的持久化模式的,專為高效率和高性能的數(shù)據(jù)庫訪問設(shè)計的,改編成一個簡單的 Python 域語言的完整套件”。它采用了數(shù)據(jù)映射模式(像 Java 中的 Hibernate)而不是 Active Record 模式(像Ruby on Rails 的 ORM)。

SQLAlchemy官網(wǎng)

SQLAlchemy 的優(yōu)缺點:

優(yōu)點:

  • 企業(yè)級 API,使得代碼有健壯性和適應(yīng)性。
  • 靈活的設(shè)計,使得能輕松完成復(fù)雜的數(shù)據(jù)查詢。

缺點:

  • 工作單元概念不常見。
  • 重量級 API,導(dǎo)致長學習曲線。

SQLAlchemy 應(yīng)用

以下是一段使用 SQLAlchemy 操作 SQLite 數(shù)據(jù)庫的代碼

# -*- coding:utf-8 -*-

from sqlalchemy import (
  create_engine,
  Column,
  Integer,
  String,
)

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///./sqlalchemy.sqlite', echo=True)

Base = declarative_base()

class User(Base):
  __tablename__ = 'users'

  id = Column(Integer, primary_key=True, autoincrement=True)
  name = Column(String)
  fullname = Column(String)
  nickname = Column(String)

  def __repr__(self):
    return "<User(name='%s', fullname='%s', nickname='%s')>" % (self.name, self.fullname, self.nickname)


db_session = sessionmaker(bind=engine)
session = db_session()

Base.metadata.create_all(engine)

user1 = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
user2 = User(name='wendy', fullname='Wendy Williams', nickname='windy')
user3 = User(name='mary', fullname='Mary Contrary', nickname='mary')

session.add(user1)
session.add(user2)
session.add(user3)
session.commit()

user = session.query(User).filter(User.id<2).all()
print(user)
user = session.query(User).filter(User.id<=5).all()
print(user)

user1.name = 'admin'
session.merge(user1)
user4 = User(name='fred', fullname='Fred Flintstone', nickname='freddy')
session.merge(user4)
session.query(User).filter(User.id==2).update({'name':'test'})
user = session.query(User).filter(User.id<=5).all()
print(user)

在以上代碼中我們完成了一下工作:

  1. 連接到數(shù)據(jù)庫「本次我們使用的是 SQLite 數(shù)據(jù)庫」。
  2. 創(chuàng)建數(shù)據(jù)庫表并將其映射到 Python 類上。
  3. 創(chuàng)建數(shù)據(jù)實例,并將其保存到數(shù)據(jù)庫中。
  4. 對保存在數(shù)據(jù)庫中的數(shù)據(jù)進行讀取和修改。

導(dǎo)入 SQLAlchemy 模塊并連接到 SQLite 數(shù)據(jù)庫

SQLAlchemy 通過 create_engine 函數(shù)來創(chuàng)建數(shù)據(jù)庫連接。create_engine 函數(shù)的第一個參數(shù)是數(shù)據(jù)了 URL,第二個參數(shù) echo 設(shè)置為 True 表示在程序的運行過程中我們可以在控制臺看到操作所涉及到的 SQL 語句。

在本次示例中我們使用的數(shù)據(jù)庫是 SQLite,你也可以使用其他數(shù)據(jù)庫。只有在調(diào)試狀態(tài)下將 echo 設(shè)置為 True,在生產(chǎn)環(huán)境請將 echo 設(shè)置為 false 或省略 echo 參數(shù)。

engine = create_engine('sqlite:///./sqlalchemy.sqlite', echo=True)

create_engine 返回的是一個 Engine 實例,它指向數(shù)據(jù)庫的一些核心接口。SQLAlchemy會根據(jù)你選擇的數(shù)據(jù)庫配置而調(diào)用對應(yīng)的 DB-API。

create_engine 函數(shù)并會不真正建立數(shù)據(jù)庫的 DB-API 連接,當調(diào)用 Engine.execute() 或 Engine.connect() 方法時才會建立連接。大多數(shù)情況下我們無需關(guān)注 Engine,SQLAlchemy 會幫我們處理。

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

將 python 類映射到數(shù)據(jù)庫表上,這個 Python 類需要時一個指定基類的子類,這個基類應(yīng)當含有ORM映射中相關(guān)的類和表的信息。這個基類可以通過 declarative_base 方法來創(chuàng)建。
Base = declarative_base()

在這個示例中使用 Base 基類創(chuàng)建了一個 User 的類來作為數(shù)據(jù)庫表。

class User(Base):
  __tablename__ = 'users'

  id = Column(Integer, primary_key=True, autoincrement=True)
  name = Column(String)
  fullname = Column(String)
  nickname = Column(String)

  def __repr__(self):
    return "<User(name='%s', fullname='%s', nickname='%s')>" % (self.name, self.fullname, self.nickname)

在 User 類中我們定義了需要映射到數(shù)據(jù)庫表上的屬性,主要包括表名稱、列的類型和名稱等。這個類至少應(yīng)包含一個名為 tablename 的屬性來給出數(shù)據(jù)庫表的名稱,及至少一個給出表的主鍵「primary key」的列。在 User 類中我們定義了表名稱為 users,定義了 id、name、fullname、nickname 四列數(shù)據(jù),并設(shè)置 id 為表的主鍵。
創(chuàng)建完成 User 類后,實際在 SQLite 數(shù)據(jù)庫中并不存在該表,此時需要使用 declarative 基類的 Metadata.create_all 在數(shù)據(jù)庫中創(chuàng)建 users 表,在 create_all 方法中我們需要傳入?yún)?shù) Engine。

通過 Metadata.create_all 傳入的 Engine 參數(shù),SQLAlchemy 自動實現(xiàn)對數(shù)據(jù)庫的連接。

Base.metadata.create_all(engine)

metadata.create_all 方法執(zhí)行完成后在 SQLite 數(shù)據(jù)庫即可查到名稱為 users 的數(shù)據(jù)表。

保存數(shù)據(jù)實例到數(shù)據(jù)庫中

將數(shù)據(jù)保存到數(shù)據(jù)庫中,我們需要 User 的實例和用于操作數(shù)據(jù)的 session。

session 是 ORM 數(shù)據(jù)的接口,可以通過 session 來操作數(shù)據(jù)庫中的數(shù)據(jù)。

使用已經(jīng)定義完成的 User 類將數(shù)據(jù)實例化。

user1 = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
user2 = User(name='wendy', fullname='Wendy Williams', nickname='windy')
user3 = User(name='mary', fullname='Mary Contrary', nickname='mary')

獲取 session 首先需要使用 sessionmaker 來得到 session 的工廠類,然后通過工廠類來獲取 session。

db_session = sessionmaker(bind=engine)
session = db_session()

session 通過 Engine 與數(shù)據(jù)庫進行關(guān)聯(lián)。session 創(chuàng)建完成后并不會立即打開與數(shù)據(jù)庫的連接,只有當我們第一使用 session 是,才會從 Engine 維護的連接池中取出一個連接來操作數(shù)據(jù)庫,這個連接在我們關(guān)閉 session 時會被釋放。
獲取 session 后可以通過 add 和 commit 方法將數(shù)據(jù)保存到數(shù)據(jù)庫中。

session.add(user1)
session.add(user2)
session.add(user3)
session.commit()

對數(shù)據(jù)庫中的數(shù)據(jù)進行查詢和修改

SQLAlchemy 通過 query 來對數(shù)據(jù)進行查詢,可以通過 filter 方法對查詢結(jié)果進行篩選。

user = session.query(User).filter(User.id<2).all()
print(user)
user = session.query(User).filter(User.id<=5).all()
print(user)

以上代碼通過 query 獲取數(shù)據(jù)庫中所有 User 數(shù)據(jù),然后通過 filter 方法篩選出 id 小于 2 和 id 小于等于 5 的數(shù)據(jù)。

數(shù)據(jù)庫的修改可以通過 merge 和 update 來實現(xiàn)

user1.name = 'admin'
session.merge(user1)
user4 = User(name='fred', fullname='Fred Flintstone', nickname='freddy')
session.merge(user4)
session.query(User).filter(User.id==2).update({'name':'test'})
user = session.query(User).filter(User.id<=5).all()
print(user)

使用 merge 修改數(shù)據(jù),當數(shù)據(jù)中存在該數(shù)據(jù)時修改,不存在是將當前數(shù)據(jù)插入數(shù)據(jù)庫中。

代碼運行結(jié)果

以上示例代碼的運行結(jié)果如下

2019-02-16 21:45:23,919 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2019-02-16 21:45:23,919 INFO sqlalchemy.engine.base.Engine ()
2019-02-16 21:45:23,919 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2019-02-16 21:45:23,919 INFO sqlalchemy.engine.base.Engine ()
2019-02-16 21:45:23,920 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("users")
2019-02-16 21:45:23,920 INFO sqlalchemy.engine.base.Engine ()
2019-02-16 21:45:23,921 INFO sqlalchemy.engine.base.Engine
CREATE TABLE users (
  id INTEGER NOT NULL,
  name VARCHAR,
  fullname VARCHAR,
  nickname VARCHAR,
  PRIMARY KEY (id)
)


2019-02-16 21:45:23,921 INFO sqlalchemy.engine.base.Engine ()
2019-02-16 21:45:23,922 INFO sqlalchemy.engine.base.Engine COMMIT
2019-02-16 21:45:23,924 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-02-16 21:45:23,925 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,925 INFO sqlalchemy.engine.base.Engine ('ed', 'Ed Jones', 'edsnickname')
2019-02-16 21:45:23,926 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,926 INFO sqlalchemy.engine.base.Engine ('wendy', 'Wendy Williams', 'windy')
2019-02-16 21:45:23,926 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,926 INFO sqlalchemy.engine.base.Engine ('mary', 'Mary Contrary', 'mary')
2019-02-16 21:45:23,927 INFO sqlalchemy.engine.base.Engine COMMIT
2019-02-16 21:45:23,929 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-02-16 21:45:23,929 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.nickname AS users_nickname
FROM users
WHERE users.id < ?
2019-02-16 21:45:23,929 INFO sqlalchemy.engine.base.Engine (2,)
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>]
2019-02-16 21:45:23,931 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.nickname AS users_nickname
FROM users
WHERE users.id <= ?
2019-02-16 21:45:23,931 INFO sqlalchemy.engine.base.Engine (5,)
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>, <User(name='wendy', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>]
2019-02-16 21:45:23,932 INFO sqlalchemy.engine.base.Engine UPDATE users SET name=? WHERE users.id = ?
2019-02-16 21:45:23,932 INFO sqlalchemy.engine.base.Engine ('admin', 1)
2019-02-16 21:45:23,933 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,933 INFO sqlalchemy.engine.base.Engine ('fred', 'Fred Flintstone', 'freddy')
2019-02-16 21:45:23,934 INFO sqlalchemy.engine.base.Engine UPDATE users SET name=? WHERE users.id = ?
2019-02-16 21:45:23,934 INFO sqlalchemy.engine.base.Engine ('test', 2)
2019-02-16 21:45:23,935 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.nickname AS users_nickname
FROM users
WHERE users.id <= ?
2019-02-16 21:45:23,935 INFO sqlalchemy.engine.base.Engine (5,)
[<User(name='admin', fullname='Ed Jones', nickname='edsnickname')>, <User(name='test', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>, <User(name='fred', fullname='Fred Flintstone', nickname='freddy')>]

由于我們設(shè)置 create_engine 中 echo 為 True,因此在執(zhí)行結(jié)果中包含了 SQLAlchemy 打印的 SQL 語句,我們可以取消 crete_engine 中的 echo

engine = create_engine('sqlite:///./sqlalchemy.sqlite')

此時的執(zhí)行結(jié)果如下:

[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>]
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>, <User(name='wendy', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>]
[<User(name='admin', fullname='Ed Jones', nickname='edsnickname')>, <User(name='test', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>, <User(name='fred', fullname='Fred Flintstone', nickname='freddy')>]

當取消 echo 后,程序運行結(jié)果中原有的 SQL 語句消失。

本文只是對 SQLAlchemy 的使用進行簡單的介紹,SQLAlchemy 本身還有很多特性和運用方法我們可以共同探討。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決python運行效率不高的問題

    解決python運行效率不高的問題

    在本篇文章中小編給大家分享了關(guān)于解決python運行效率不高的問題,有需要的朋友們可以跟著學習下。
    2020-07-07
  • 一文講解python中的繼承沖突及繼承順序

    一文講解python中的繼承沖突及繼承順序

    python支持多繼承,如果子類沒有重寫方法,則默認會調(diào)用父類的方法,本文主要介紹了一文講解python中的繼承沖突及繼承順序,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Python?裝飾器常用的創(chuàng)建方式及源碼示例解析

    Python?裝飾器常用的創(chuàng)建方式及源碼示例解析

    裝飾器(decorator)是一種高級Python語法,可以對一個函數(shù)、方法或者類進行加工,這篇文章主要介紹了Python?裝飾器常用的創(chuàng)建方式及解析,需要的朋友可以參考下
    2022-04-04
  • python 梯度法求解函數(shù)極值的實例

    python 梯度法求解函數(shù)極值的實例

    今天小編就為大家分享一篇python 梯度法求解函數(shù)極值的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python中常見的矩陣運算詳解

    Python中常見的矩陣運算詳解

    這篇文章主要介紹了Python中常見的矩陣運算詳解,所謂的數(shù)據(jù)處理,其本質(zhì)大都可以歸為矩陣運算,因為需要處理的數(shù)據(jù)大都是矩陣或向量的形式,一個工具適不適合做數(shù)據(jù)處理,一個重要的指標的就是支不支持矩陣運算,需要的朋友可以參考下
    2023-08-08
  • Pytorch中的廣播機制詳解(Broadcast)

    Pytorch中的廣播機制詳解(Broadcast)

    這篇文章主要介紹了Pytorch中的廣播機制詳解(Broadcast),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • python調(diào)用dll出現(xiàn)精度問題解決

    python調(diào)用dll出現(xiàn)精度問題解決

    本文主要介紹了python調(diào)用dll出現(xiàn)精度問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • 如何利用opencv對拍攝圖片進行文字識別

    如何利用opencv對拍攝圖片進行文字識別

    在有些工程中有時候我們需要對圖片文字識別,下面這篇文章主要給大家介紹了關(guān)于如何利用opencv對拍攝圖片進行文字識別的相關(guān)資料,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2024-03-03
  • Python實現(xiàn)貪吃蛇小游戲(雙人模式)

    Python實現(xiàn)貪吃蛇小游戲(雙人模式)

    這篇文章主要為大家詳細介紹了Python實現(xiàn)雙人模式的貪吃蛇小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 解決Django Static內(nèi)容不能加載顯示的問題

    解決Django Static內(nèi)容不能加載顯示的問題

    今天小編就為大家分享一篇解決Django Static內(nèi)容不能加載顯示的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07

最新評論