久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python中直接撰寫(xiě)SQL語(yǔ)句

 cnzrp 2023-10-07 發(fā)布于山西

現(xiàn)代的編程語(yǔ)言在進(jìn)行數(shù)據(jù)庫(kù)操作時(shí)候,往往都是使用ORM組件(Object Relational Mapping)而不是直接鏈接到數(shù)據(jù)庫(kù)中然后自己寫(xiě)SQL,,ORM可以幫我們厘清數(shù)據(jù)關(guān)系,、自動(dòng)進(jìn)行內(nèi)置的Sql注入防護(hù)等等,總之好處多多,。但是往往有點(diǎn)不太自由束手束腳不太放得開(kāi),。

在早期的PHP寫(xiě)Web應(yīng)用時(shí)候基本都是自己拼Sql語(yǔ)句的,當(dāng)然帶來(lái)大量的注入式漏洞,。時(shí)下在Golang語(yǔ)言中,,其語(yǔ)言?xún)?nèi)置了數(shù)據(jù)庫(kù)的Sql包,可以讓用戶(hù)直接通過(guò)非ORM,、非查詢(xún)構(gòu)建器方法來(lái)與數(shù)據(jù)庫(kù)交互,。即使在一些Golang大型項(xiàng)目中,寫(xiě)Sql語(yǔ)句也是很常見(jiàn)的,。

而現(xiàn)在最流行,,用戶(hù)量最大的Python語(yǔ)言中沒(méi)有任何內(nèi)置的支持?jǐn)?shù)據(jù)庫(kù)交互的東西,這也給初學(xué)者進(jìn)行數(shù)據(jù)庫(kù)操作增加麻煩,。本文中蟲(chóng)蟲(chóng)就給大家介紹如何在Python中通過(guò)適配器直接編寫(xiě)Sql語(yǔ)句,,從而達(dá)到間接學(xué)習(xí)數(shù)據(jù)庫(kù)和Sql語(yǔ)言的目的。

本文主要目的在于學(xué)習(xí),,可以實(shí)現(xiàn)在Python中不依賴(lài)查詢(xún)生成器和ORM熟練的拼寫(xiě)和處理Sql,,并能將這些邏輯抽象打包,最后可以實(shí)現(xiàn)MVC三層架構(gòu),,實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作和業(yè)務(wù)邏輯(以及表現(xiàn)層)分開(kāi),。

從一個(gè)簡(jiǎn)單的例子開(kāi)始:

# user/domain.py
@dataclass
class User:
id: int = None
dt_created: datetime = None
username: str = None
email: str = None
mobile: Optional[str] = None

User是可能看到的名為SQL表的字面定義user。 這包括喜歡包含在所有SQL表中的一些列:

id(主鍵),。

dt_created日期時(shí)間值,通常默認(rèn)為NOW(),。

所有字段默認(rèn)為None,,這可以姐可以執(zhí)行SELECT不包含表中所有列的查詢(xún),,同時(shí)仍然能夠?qū)⑿修D(zhuǎn)換為User對(duì)象。所有列都是NOT NULL除了mobile,,代碼中利用Optional鍵入提示以強(qiáng)調(diào)該字段允許NULL,。

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

# user/repository.py
from abc import ABC, abstractmethod
class UserRepository(ABC):
@abstractmethod
def new(self, new_row: User) -> int:
'''
Create a new record and returns the new id value.
'''
pass

@abstractmethod
def get_by_id(self, id_val: int) -> User:
'''
Get a single record by ID value.
'''
pass

現(xiàn)在可以創(chuàng)建的存儲(chǔ)庫(kù),創(chuàng)建的存儲(chǔ)庫(kù)是一個(gè)抽象類(lèi),,可以確保任何未來(lái)的實(shí)現(xiàn)都需要遵循規(guī)則,。

為了方便,我們直接使用psycopg3來(lái)實(shí)現(xiàn)PostgreSQL鏈接,,其他數(shù)據(jù)庫(kù)類(lèi)型都可以隨時(shí)擴(kuò)展:

# external/postgres.py
import psycopg
from psycopg.rows import class_row
from config import get_config
cfg = get_config()
conn = psycopg.connect(
dbname=cfg.database_name,
user=cfg.database_username,
password=cfg.database_password,
host=cfg.database_host,
)
def new_cursor(name=None, row_factory=None):
if name is None:
name = ''
if row_factory is None:
return conn.cursor(name=name)
return conn.cursor(name=name, row_factory=class_row(row_factory))

首先,,根據(jù)配置設(shè)置連接,連接到數(shù)據(jù),。

結(jié)果會(huì)返回psycopg游標(biāo)的函數(shù),。psycopg3包含一個(gè)自定義行工廠,這個(gè)功能非常有用,。

# user/repository.py
from external.postgres import conn, new_cursor
class UserPostgreSQL(UserRepository):
def new(self, new_row: User) -> int:
with new_cursor() as cur:
cur.execute(
'''
INSERT INTO user
(username, email)
VALUES
(%s, %s)
ON CONFLICT (email)
DO NOTHING
RETURNING id;
''',
(
new_row.username,
new_row.email
),
)

new_id = cur.fetchone()
if new_id and len(new_id):
conn.commit()
new_id = new_id[0]
else:
new_id = 0

return new_id
def get_by_id(self, id_val: int) -> User:
with new_cursor(name='get_by_id', row_factory=User) as cur:
cur.execute(
'''
SELECT *
FROM user
WHERE id = %s
''',
(id_val,),
)

return cur.fetchone()

def new_user_repo() -> UserRepository:
return UserPostgreSQL()

你會(huì)注意到new()使用基本光標(biāo),,但是get_by_id()游標(biāo)使用帶有類(lèi)行工廠的 ,這這樣返回的行將是類(lèi)型User對(duì)象,。

new_user_repo()在假設(shè)的業(yè)務(wù)邏輯中使用的函數(shù):

from user.repository import *
user_repo = new_user_repo()

row = User()
row.username = 'chognchong'
row.email = 'chongchong(at)someadress'

# Create a new record.
new_id = user_repo.new(row)

# Fetch the record we just created.
new_row = user_repo.get_by_id(new_id)
# User(id=1, dt_created=datetime.datetime(2023, 8, 9, 23, 8, 14, 974074, tzinfo=datetime.timezone.utc), username=' chognchong', email=' chongchong(at)someadress ', mobile=None)

new_user_repo()可以修改為返回任何實(shí)現(xiàn)UserRepository,,可以是PostgreSQL,也可能是MySQL實(shí)現(xiàn),,或者SQLite實(shí)現(xiàn),,甚至可能是用于測(cè)試目的的模擬數(shù)據(jù)庫(kù)。

總結(jié)

在編程屆各種技術(shù)層出不窮,,迭代替換,,唯一常青樹(shù)不變的,SQL是一個(gè),。編寫(xiě)Sql可以讓我們更加輕松自由和數(shù)據(jù)庫(kù)打交道,,當(dāng)然對(duì)于初學(xué)者更是莫大的寶藏,與其看看幾個(gè)月就會(huì)被淘汰的ORM復(fù)雜語(yǔ)法框架,,不如直接深入純的Sql層,。當(dāng)然直接寫(xiě)Sql一直有風(fēng)險(xiǎn),尤其是線上系統(tǒng),,請(qǐng)謹(jǐn)慎使用,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多