前言:該筆記是本人學習SQLAlchemy官方文檔整理得來郑兴。
查看SQLAlchemy版本
>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.0.15'
>>>
連接數(shù)據(jù)庫
本教程中我們將使用postgresql數(shù)據(jù)庫精绎,連接數(shù)據(jù)庫我們使用create_engine():
>>> >>> from sqlalchemy import create_engine
>>> engine = create_engine('postgresql://ricky:passwd@localhost/my_db', echo=True)
關于SQLAlchemy連接不同的數(shù)據(jù)庫的URL設置衰齐,請自行搜索娘香。
echo參數(shù)是設置SQLAlchemy日志顯示的快捷方式锉屈,這樣我們在python命令行中執(zhí)行的命令都會在下面顯示出日志信息(這里我們能清楚看到只想的SQL語句詳細內容)荤傲。如果我們不想看見執(zhí)行的詳細過程,可以將echo
設置為False
颈渊。
create_engine()函數(shù)返回一個Engin
的實例遂黍,代表著訪問數(shù)據(jù)庫的接口。
延遲連接
當create_engine()
第一次調用俊嗽,它沒有嘗試去連接數(shù)據(jù)庫雾家,僅僅是當我們執(zhí)行數(shù)據(jù)庫操作時,才會去連接數(shù)據(jù)庫绍豁。
定義映射
當我們在使用ORM
的時候芯咧,數(shù)據(jù)庫中的一張表對應著我們的一個類,我們使用declarative_base()
創(chuàng)建一個基類竹揍。
>>> from sqlalchemy.ext.declarative import declarative_base
>>> Base = declarative_base()
現(xiàn)在我們有了一個基類Base
,我們可以定義很多映射的類,先從一張完整的表格,名字為Users
開始,一個新的User
類將會映射到我們的那種表格上敬飒,在類中我們定義關于表格的詳細信息。主要是表名鬼佣、列名和數(shù)據(jù)類型驶拱。
>>> 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(naem=%s, fullname=%s, password=%s)>" % (self.name, self.fullname, self.password)
...
一個最簡單的類需要一個__tablename__
屬性,和至少一行Column
和一個外鍵primary key
晶衷。
Tip######
User類定義了一個__repr__()
方法蓝纲,但是這個是可選的阴孟,我們在這里定義是為了打印出類的對象的內容。
創(chuàng)建一個模型
通過聲明系統(tǒng)税迷,我們已經(jīng)定義了我們表格的詳細信息永丝,我們可以通過__table__
屬性來看我們定義的類
>>> User.__table__
Table('users', MetaData(bind=None),
Column('id', Integer(), table=<users>, primary_key=True, nullable=False),
Column('name', String(), table=<users>),
Column('fullname', String(), table=<users>),
Column('password', String(), table=<users>), schema=None)
當我們定義了我們的類,聲明系統(tǒng)使用一個Python的metaclass
來執(zhí)行其他任務箭养,一旦這個類聲明完成慕嚷。
表的對象是一個更大的稱為元數(shù)據(jù)集合的一個成員。當我們使用這個系統(tǒng)毕泌,可以使用這個對象.metadata
屬性聲明我們基類的屬性喝检。
MetaData是一個注冊表,當我們的數(shù)據(jù)庫不存在一個users
表格撼泛,我們可以使用MetaData
去創(chuàng)建一個不存在的表格挠说,我們調用MetaData.create_all()
方法,Engine
作為一個數(shù)據(jù)庫的連接愿题。
>>> Base.metadata.create_all(engine)
SELECT ...
PRAGMA table_info("users")
()
CREATE TABLE users (
id INTEGER NOT NULL, name VARCHAR,
fullname VARCHAR,
password VARCHAR,
PRIMARY KEY (id)
)
()
COMMIT
Minimal Table Descriptions vs. Full Descriptions
在上面的聲明一個表中的列時损俭,我們注意到列的數(shù)據(jù)類型為字符串,但是沒有指定長度潘酗;在SQLite和PostgreSQL中這樣的聲明是合法的杆兵,但是在其他的數(shù)據(jù)庫中是不允許的。所以仔夺,如果運行這個教程在洽談的數(shù)據(jù)庫中琐脏,可能會報錯。最好我很使用下面的聲明方式缸兔。
Column(String(50))
另外在Firebird和Oracle數(shù)據(jù)庫中要求sequences去生成一個新的外鍵約束骆膝。你可以使用序列來構造。
from sqlalchemy import Sequence
Column(Integer, Sequence('user_id_seq'), primary_key=True)
完整的Table的定義為:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
password = Column(String(12))
def __repr__(self):
return "<User(name='%s', fullname='%s', password='%s')>" % (
self.name, self.fullname, self.password)
創(chuàng)建一個映射的類的對象
我們來創(chuàng)建一個User
的對象.
>>> ed_user = User(name='ricky', fullname='yuziyong', password='123')
>>> ed_user.name
'ricky'
>>> ed_user.password
'123'
>>> ed_user.fullname
'yuziyong'
>>> str(ed_user.id)
'None'
盡管我們沒有特別在構造函數(shù)指定灶体,但是id
屬性仍然產(chǎn)生了一個值None,當我們訪問它阅签,SQLAlchemy的工具通常會產(chǎn)生一個默認值。