日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

SQLAlchemy 快速入门、基础知识

發布時間:2024/6/21 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 SQLAlchemy 快速入门、基础知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SQLAlchemy 是Python 編程語言下的一款開源軟件。提供了SQL工具包及對象關系映射(ORM)工具。

ORM, 全稱Object Relational Mapping, 中文叫做對象關系映射,通過ORM,我們可以像操作類一樣使用數據庫的數據
ORM把表映射成類,把行作為實例,把字段作為屬性,ORM在執行對象操作的時候會把對相應的操作轉換為數據庫原生
語句的方式來完成數據庫開發工作


SQLAlchemy 至少需要3部分代碼,

定義表
定義數據庫連接
進行增、刪、改、查等邏輯操作

'Hello World'入門

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

from sqlalchemy import Column, Integer, String
class User(Base):
     __tablename__ = 'users'

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

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

注意

以上的例子來自SQLAlchemy 官網,數據庫用的是SQLite,沒有長度限制的字符串是有效的數據類型,但在MySql中則
不然,此時可以使用String的帶參數形式,如String(10)來實現指定長度。

關鍵點解釋

首先導入sqlalchemy.ext.declarative,declarative_base,并定義它的實例。所有表必須繼承自Base。之所以這樣,可以看原版英文

When using the ORM, the configurational process starts by describing the database tables we’ll be dealing with, and then by defining our own classes which will be mapped to those tables. In modern SQLAlchemy, these two tasks are usually performed together, using a system known as Declarative, which allows us to create classes that include directives to describe the actual database table they will be mapped to.
之后利用Base 定義了一個User類

使用tablename屬性定義了表在數據庫中實際的名稱users
引入sqlalchemy包中的Column、Intege、String類型,定義User表的數據列。

定義數據庫連接

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

db_connect_string='sqlite://'

engine = create_engine(db_connect_string)
SessionType = scoped_session(sessionmaker(bind=engine,expire_on_commit=False))
def GetSession():
    return SessionType()

from contextlib import contextmanager
@contextmanager
def session_scope():
    session = GetSession()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

代碼解析

引入數據庫和會話引擎:sqlalchemy.create_engine,sqlalchemy.orm.scoped_session,sqlalchemy.orm.sessionmaker,其中,create_engine傳入了
一個數據庫的URI,sqlite://表示使用了一個SQLite的內存型數據庫。URI的格式如下:
dialect+driver://username:password@host:port/database。dialect是數據庫的實現,比如MySql,PostgreSQL,SQLite。driver是Python對應的驅動,
如果不指定,會選擇默認的驅動。比如MySQL的默認驅動是MySQldb: engine=create_engine('mysql+mysqldb://scott:tiger@localhost/foo'),默認驅動可以省略。

定義數據庫連接需要用到的字符串。

用create_engine建立數據庫引擎。

使用上下文管理器定義的scoped_session,建立會話。

為了使之后的數據庫操作的代碼能夠自動進行事務處理,定義了上下文函數session_scope()。在Python中定義上下文函數的方法
是為其加入contextlib包中的contextmanager裝飾器。在上下文函數中執行如下邏輯:在函數開始時建立數據庫會話,此時會自動建立一個數據庫事務;
當發生異常是回滾事務;當退出時關閉連接。在關閉連接時會自動進行事務處理*

SQLAlchemy 同樣可以執行原生SQL對象

from sqlalchemy import create_engine

def exec_raw_sql(eng, sql):
    with eng.connect() as con:
        return list(con.execute(sql))

exec_raw_sql 是自定義的函數,需要傳入SQLAlchemy 數據庫連接實例化的引擎,具體為
eng = create_engine(db_uri),con.execute返回的對象需要用list轉化一下,因為返回的是數據庫查詢對象。

查詢條件設置

SQLAlchemy 查詢條件被稱為過濾器

等值過濾器

session.query(Account).filter(Account.user_name == "Jackey") 
session.query(Account).filter(Account.salary == 2000)

不等過濾器(!=,<,>,<=,>=)

session.query(Account).filter(Account.user_name != "Jackey") 
session.query(Account).filter(Account.salary >= 2000)

模糊查詢--like 僅支持字符串

session.query(Account).filter(Account.user_name.like('%i%'))

包括過濾器(in_)

session.query(Account).filter(Account.user_name.in_(['xiaohong','xiaoming','xiaoli']))

判斷是否為空(is NULL, is not NULL)
空值NULL是數據庫字段中比較特殊的值。在SQLAlchemy中支持對字段是否為空進行判斷。判讀時可以用等值,不等值過濾器篩選,亦可用is,isnot進行篩選。

session.query(Account).filter(Account.salary == None)
session.query(Account).filter(Account.salary.is_(None))
session.query(Account).filter(Account.salary != None)
session.query(Account).filter(Account.isnot(None))

非邏輯(~)

session.query(Account).filter(~Account.id.in_([1,3,5]))

與邏輯(and_)

session.query(Account).filter(Account.title=='Engineer',Account.salary=3000) 
session.query(Account).filter(and_(Account.title=="engineer",Account.salary=3000))

或邏輯(or_)

session.query(Account).filter(or_(Account.title=="engineer",Account.salary=3000))

關系操作

SQLAlchemy 支持數據庫模型的一對一,一對多,多對多關系。支持通過將各個表通過主鍵,外鍵聯系起來。

以下是一個簡單的數據表 E-R圖映射,其中,class表與student表是一對多關系,class表與teacher表之間是多對多關系

將E-R圖轉化為SQLAlchemy模型定義的代碼文件如下

from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Class(Base):
    __tablename__ = 'class'
    class_id = Column(Integer, primary_key=True)
    name= Column(String(50))
    level = Column(Integer)
    address = Column(String(50))

    class_teachers = relationship("ClassTeacher", backref="class")
    students = relationship("Student", backref="class")
	
class Student(Base):
    __tablename__ = 'student'
    student_id = Column(Integer, primary_key=True)
    name= Column(String(50))
    age = Column(Integer)
    gender= Column(String(10))
    address= Column(String(50))
    class_id = Column(Integer, ForeignKey('class.class_id'))

class Teacher(Base):
    __tablename__ = 'teacher'
    teacher_id = Column(Integer, primary_key=True)
    name= Column(String(50))
    gender= Column(String(10))
    telephone= Column(String(50))
    address= Column(String(50))
    class_teachers = relationship("ClassTeacher", backref="teacher")

class ClassTeacher(Base):
    __tablename__ = 'class_teacher'
    teacher_id = Column(Integer, ForeignKey('teacher.teacher_id'), primary_key=True)
    class_id = Column(Integer,ForeignKey('class.class_id'),primary_key=True)

代碼說明

外鍵設置:在列的定義中,為Column傳入ForeignKey進行外鍵設置
class_id = Column(Integer, ForeignKey('class.class_id'))

關系設置:通過relationship關鍵字在父模型中建立對子表的引用,例如Class模型中的關系設置如下
students = relationship("Student", backref="class")
注意students 即student表中所有擁有相同class_id的記錄的集合,SQLAlchemy中Class表的實例可直接通過students屬性訪問到。

class_=session.query(Class).filter(Class.name==u"三年二班").first()
for student in class_.students:
    print u"學生姓名:%s, 年齡:%d" %(student.name, student.age)

另外,backref參數如果設置了,則表示同時設置了父表(一對多關系中的一)對子表的引用。
即student表的實例可以通過class屬性訪問與其關聯的class記錄。

多對多關系的使用,通過ClassTeacher表實現。其中分別設置模型Class和Teacher的外鍵,并且在父模型中設置相應的relationship實現。
多對多關系也可以想象成一個關聯表,分別對兩個父表實現了多對一的關系。班級與老師之間為多對多關系,如下代碼可以打印特定班級所有老師的信息

class_=session.query(Class).filter(Class.name==u"三年二班").first()
for class_teacher in class_.class_teachers:
    teacher = class_teacher.teacher			
    print u"老師姓名:%s, 電話:%s"%(teacher.name, teacher.telephone)

級聯

級聯是在一對多關系中父表對字表進行聯動操作的數據庫術語。因為父表與字表通過外鍵關聯,所以對父表或字表的增刪改查都會對另一張表也產生相應的

影響。

級聯定義
SQLAlchemy 中的級聯通過父表中的relationship屬性定義cascade參數來實現,代碼如下:


from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref

Base = declarative_base()

class Class(Base):
    __tablename__ = 'class'
    class_id = Column(Integer, primary_key=True)
    name= Column(String(50))
    level = Column(Integer)
    address = Column(String(50))

    students = relationship("Student", backref="class_", cascade="all")
	
class Student(Base):
    __tablename__ = 'student'
    student_id = Column(Integer, primary_key=True)
    name= Column(String(50))
    age = Column(Integer)
    gender= Column(String(10))
    address= Column(String(50))
    class_id = Column(Integer, ForeignKey('class.class_id'))

上述代碼定義了class表和student表。一對多的關系由父表中的relationship屬性students進行定義。relationship中的cascade屬性
定義了要在該關系上實現的級聯方法為"all", 其他的cascade屬性有save_update,merge,expunge,delete,delete-orphan,refresh-expire,all
其中save_update,delete,delete_orphan與父表的數據變化有關,其他與session操作有關。多個cascade屬性可以通過逗號分隔并同時賦值給
cascade。如

students = relationship("Student",backref="class_",cascade="save-update,merge,expunge")

總結

以上是生活随笔為你收集整理的SQLAlchemy 快速入门、基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。