W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
很多人更傾向于使用 SQLAlchemy 進(jìn)行數(shù)據(jù)庫(kù)操作。在這種情況下,建議您使用 包的而不是模塊的方式組織您的應(yīng)用代碼,并將所有的模型放置到一個(gè)單獨(dú)的模塊中 (大型應(yīng)用)。盡管這并非必要,但是這么做將會(huì)讓程序的結(jié)構(gòu)更加 明晰。
使用 SQLAlchemy 有四種常用的方法,我們?cè)谙旅媪谐隽诉@幾種方法的基本使用 框架:
因?yàn)?SQLAlchemy 是一個(gè)常用的數(shù)據(jù)庫(kù)抽象層和數(shù)據(jù)庫(kù)關(guān)系映射包(ORM),并且需要 一點(diǎn)點(diǎn)設(shè)置才可以使用,因此存在一個(gè) Flask 擴(kuò)展幫助您操作它。如果您想要快速 開(kāi)始使用,那么我們建議您使用這種方法。
您可以從 PyPI 下載到 Flask-SQLAlchemy
SQLAlchemy 中的 declarative 擴(kuò)展是最新的使用 SQLAlchemy 的方法。它允許您 同時(shí)定義表和模型,就像 Django 一樣工作。除了下文所介紹的內(nèi)容外,我們建議您 參考 declarative 擴(kuò)展的官方文檔。
這是一個(gè) database.py 模塊的例子:
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
# 在這里導(dǎo)入所有的可能與定義模型有關(guān)的模塊,這樣他們才會(huì)合適地
# 在 metadata 中注冊(cè)。否則,您將不得不在第一次執(zhí)行 init_db() 時(shí)
# 先導(dǎo)入他們。
import yourapplication.models
Base.metadata.create_all(bind=engine)
為了定義您的模型,僅僅構(gòu)造一個(gè)上面代碼編寫(xiě)的 Base 類(lèi)的子類(lèi)。如果您好奇 為何我們?cè)谶@里不用擔(dān)心多線(xiàn)程的問(wèn)題(就像我們?cè)谙惹笆褂?g 對(duì)象操作 SQLite3 的例子一樣):那是因?yàn)?SQLAlchemy 已經(jīng)在 scoped_session 類(lèi)當(dāng)中為我們完成了這些任務(wù)。
在您的應(yīng)用當(dāng)中以一個(gè)顯式調(diào)用 SQLAlchemy , 您只需要將如下代碼放置在您應(yīng)用 的模塊中。Flask 將會(huì)在請(qǐng)求結(jié)束時(shí)自動(dòng)移除數(shù)據(jù)庫(kù)會(huì)話(huà):
from yourapplication.database import db_session
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
這是一個(gè)模型的例子(將代碼放入 models.py 或類(lèi)似文件中):
from sqlalchemy import Column, Integer, String
from yourapplication.database import Base
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
email = Column(String(120), unique=True)
def __init__(self, name=None, email=None):
self.name = name
self.email = email
def __repr__(self):
return '<User %r>' % (self.name)
您可以使用 init_db 函數(shù)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù):
>>> from yourapplication.database import init_db
>>> init_db()
按照如下方式將數(shù)據(jù)實(shí)體插入數(shù)據(jù)庫(kù):
>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()
查詢(xún)代碼也很簡(jiǎn)單:
>>> User.query.all()
[<User u'admin'>]
>>> User.query.filter(User.name == 'admin').first()
<User u'admin'>
手動(dòng)實(shí)現(xiàn) ORM (對(duì)象關(guān)系映射) 相比前面的顯式調(diào)用方法,既有一些優(yōu)點(diǎn),也有一些缺點(diǎn)。 主要差別在于這里的數(shù)據(jù)表和模型是分開(kāi)定義的,然后再將其映射起來(lái)。這提供了更大的靈活性, 但是會(huì)增加了代碼量。通常來(lái)說(shuō)它和上面顯式調(diào)用的工作的方式很相似,所以請(qǐng)確保您的應(yīng)用已經(jīng) 被合理分割到了包中的不同模塊中。
這是一個(gè) database.py 模塊的例子:
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData()
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
def init_db():
metadata.create_all(bind=engine)
與顯式調(diào)用相同,您需要在請(qǐng)求結(jié)束后關(guān)閉數(shù)據(jù)庫(kù)會(huì)話(huà)。將下面的代碼 放到您的應(yīng)用程序模塊中:
from yourapplication.database import db_session
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
下面是一個(gè)數(shù)據(jù)表和模型的例子(將他們放到 models.py 當(dāng)中):
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from yourapplication.database import metadata, db_session
class User(object):
query = db_session.query_property()
def __init__(self, name=None, email=None):
self.name = name
self.email = email
def __repr__(self):
return '<User %r>' % (self.name)
users = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(50), unique=True),
Column('email', String(120), unique=True)
)
mapper(User, users)
查詢(xún)和插入操作和上面所給出的例子是一樣的。
如果您僅用到數(shù)據(jù)庫(kù)系統(tǒng)和 SQL 抽象層,那么您只需要引擎部分:
from sqlalchemy import create_engine, MetaData
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData(bind=engine)
然后您就可以像上文的例子一樣聲明數(shù)據(jù)表,或者像下面這樣自動(dòng)加載他們:
users = Table('users', metadata, autoload=True)
您可以使用 insert 方法插入數(shù)據(jù),我們需要先獲取一個(gè)數(shù)據(jù)庫(kù)連接,這樣 我們就可以使用“事務(wù)”了:
>>> con = engine.connect()
>>> con.execute(users.insert(), name='admin', email='admin@localhost')
SQLAlchemy 將會(huì)為我們自動(dòng)提交對(duì)數(shù)據(jù)庫(kù)的修改。
查詢(xún)數(shù)據(jù)可以直接通過(guò)數(shù)據(jù)庫(kù)引擎,也可以使用一個(gè)數(shù)據(jù)庫(kù)連接:
>>> users.select(users.c.id == 1).execute().first()
(1, u'admin', u'admin@localhost')
返回的結(jié)果也是字典樣式的元組:
>>> r = users.select(users.c.id == 1).execute().first()
>>> r['name']
u'admin'
您也可以將 SQL 語(yǔ)句的字符串傳入到 execute() 函數(shù)中:
>>> engine.execute('select * from users where id = :1', [1]).first()
(1, u'admin', u'admin@localhost')
更多 SQLAlchemy 相關(guān)信息,請(qǐng)參考 其網(wǎng)站.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: