SQLAlchemy使用方法

SQLAlchemy學習記錄

一、關係定義

(一)一對多關係

onetomany

表示一對多的關係時,在子表類中通過 foreign key (外鍵)引用父表類。

然後,在父表類中通過 relationship() 方法來引用子表的類:

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    username = Column(String(64), nullable=False, index=True)
    password = Column(String(64), nullable=False)
    email = Column(String(64), nullable=False, index=True)
    articles = relationship('Article')

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.username)


class Article(Base):
    __tablename__ = 'articles'

    id = Column(Integer, primary_key=True)
    title = Column(String(255), nullable=False, index=True)
    content = Column(Text)
    user_id = Column(Integer, ForeignKey('users.id'))

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.title)

每篇文章有一個外鍵指向 users 表中的主鍵 id, 而在 User 中使用 SQLAlchemy 提供的 relationship 描述 關係。而用戶與文章的之間的這個關係是雙向的,所以我們看到上面的兩張表中都定義了 relationship

SQLAlchemy 提供了 backref 讓我們可以只需要定義一個關係:

articles = relationship('Article', backref='author')

添加了這個就可以不用再在 Article 中定義 relationship

(二)一對一關係

一對一是兩張表之間本質上的雙向關係

要做到這一點,只需要在一對多關係基礎上的父表中使用 uselist 參數來表示

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    username = Column(String(64), nullable=False, index=True)
    password = Column(String(64), nullable=False)
    email = Column(String(64), nullable=False, index=True)
    # articles = relationship('Article', backref='author')
    userinfo = relationship('UserInfo', backref='user', uselist=False)

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.username)


class UserInfo(Base):
    __tablename__ = 'userinfos'

    id = Column(Integer, primary_key=True)
    name = Column(String(64))
    qq = Column(String(11))
    phone = Column(String(11))
    link = Column(String(64))
    user_id = Column(Integer, ForeignKey('users.id'))

定義方法和一對多相同,只是需要添加 userlist=False

(三)多對多關係

多對多關係會在兩個類之間增加一個關聯的表。

這個關聯的表在 relationship() 方法中通過 secondary 參數來表示。

通常的,這個表會通過 MetaData 對象來與聲明基類關聯,所以這個 ForeignKey 指令會使用鏈接來定位到遠程的表:

定義中間表可以定義中間關係表相關的類,也可以直接通過Base.metdata生成對應關係表對象,不過基於code first準則,還是推薦將中間關係寫成類。

構建第三張關係類實現多對多。

article_tag = Table(
    'article_tag', Base.metadata,
    Column('article_id', Integer, ForeignKey('articles.id')),
    Column('tag_id', Integer, ForeignKey('tags.id'))
)

class Tag(Base):
    __tablename__ = 'tags'

    id = Column(Integer, primary_key=True)
    name = Column(String(64), nullable=False, index=True)

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.name)

二、增刪改查

from sqlalchemy import Column, String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 連接數據庫
engine = create_engine('mysql+pymysql://root:123456@localhost:3306/test')  # 創建數據庫引擎

# 建立會話
DBSession = sessionmaker(bind=engine)
session = DBSession() #類似cursor

# 創建基類
Base = declarative_base()


# 創價類映射到表
class User(Base):
    __tablename__ = 'user'

    id = Column(String(20), primary_key=True)
    name = Column(String(20))


# help(session.add)

# 增加記錄add
new_user = User(id='1', name='lbq')
session.add(new_user)

# 查詢記錄query
user1 = session.query(User).filter(User.name == 'lbq').one()

# 更改記錄
print('更改操作開始')
user1.name = 'nihao'
count_lbq = session.query(User).filter(User.name == 'lbq').count()
print('姓名爲lbq的數量爲', count_lbq)
count_nihao = session.query(User).filter(User.name == 'nihao').count()
print('姓名爲nihao的數量爲', count_nihao)
print('更改操作開始')

# 刪除記錄delete
print('刪除操作開始')
user = session.query(User).filter(User.name == 'nihao').one()
session.delete(user)
user_nihao = session.query(User).filter(User.name == 'nihao').count()
print('姓名爲nihao的數量爲', count_nihao)
print('刪除操作結束')

session.commit()
session.close()

三、類映射到數據庫

方法一

from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey
from sqlalchemy.orm import mapper
 
metadata = MetaData()
 
user = Table('user', metadata,
            Column('id', Integer, primary_key=True),
            Column('name', String(50)),
            Column('fullname', String(50)),
            Column('password', String(12))
        )
 
class User(object):
    def __init__(self, name, fullname, password):
        self.name = name
        self.fullname = fullname
        self.password = password
 
mapper(User, user) 

方法二

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

engine = create_engine("mysql+pymysql://用戶名:密碼@IP/數據庫名稱?charset=utf8")

Base = declarative_base() #生成orm基類,執行SQL語句的類就繼承Base

class User(Base):
    __tablename__ = 'user'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
    
    def __repr__(self): #如果想讓它變的可讀,只需在定義表的類下面加上這樣的代碼
        return "<id:%s name:%s password:%s>\n"%(self.id,self.name,self.password)
      
Base.metadata.create_all(engine) #創建表結構
#1 Base是上面定義的orm父類,metadata.create_all是他的方法
#2 engine是連接數據庫的引擎
#3 執行create_all(engine)將會執行所有繼承Base的語句

四、對應數據庫類型

數據類型 python數據類型 說明
Integer int 整形
String str 字符串
Float float 浮點型
DECIMAL decimal.Decimal 定點型
Boolean bool 布爾型
Date datetime.date 日期
DateTime datetime.datetime 日期和時間
Time datetime.time 時間
Enum str 枚舉類型
Text str 文本類型
LongText str 長文本類型

五、基礎指令

檢查sqlalchemy版本

import sqlalchemy
sqlalchemy.__version__

初始化數據庫連接

from sqlalchemy import create_engine
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')

創建DBSession類型

DBSession = sessionmaker(bind=engine)

創建對象基類

Base = declarative_base()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章