SQLALchemy如何將SQL語句編譯為特定數據庫方言

最近在一個使用fastapi+tortoise-orm的項目中,需要將orm的語句編譯成特定數據庫方言,但是查詢了官方文檔及一些資料卻找不到合適的方法論😔,于是乎我就把目光放到了sqlalchemy身上,東找西找給我找著了。話不多說,請看代碼。

方法1:

import sqlalchemy.dialects.mysql
from sqlalchemy import Integer, String, Column
from sqlalchemy.orm import declarative_base
from sqlalchemy.sql import insertBase = declarative_base()class Student(Base):__tablename__ = 'student'id = Column(Integer, primary_key=True, index=True)name = Column(String, index=True, comment="名稱")age = Column(Integer, index=True, comment="年齡")def generate_sql(instance):stmt = insert(instance.__class__).values({c.name: getattr(instance, c.name) for c in instance.__table__.columns})return stmt.compile(dialect=sqlalchemy.dialects.mysql.dialect(), compile_kwargs={"literal_binds": True})
ikun = Student(id=1, name="ikun", age=30)
jay = Student(id=1, name="jay", age=26)
print(generate_sql(ikun)) # INSERT INTO student (id, name, age) VALUES (1, 'ikun', 30)
print(generate_sql(jay))  # INSERT INTO student (id, name, age) VALUES (1, 'jay', 26)

上面代碼通過insert() 創建一個 INSERT 語句對象,然后獲取模型實例的對應列的值,使用stmt.compile編譯成mysql的方言。但是這個方法對于json類型的字段會編譯失敗,出現

sqlalchemy.exc.CompileError: No literal value renderer is available for literal value "['唱跳', 'rap', '籃球']" with datatype JSON

的錯誤提示。

因此,介紹下一個方法。

方法2:

import sqlalchemy.dialects.mysql
from sqlalchemy import Integer, String, Column, JSON, text
from sqlalchemy.orm import declarative_base
from sqlalchemy.sql.compiler import SQLCompilerBase = declarative_base()class Student(Base):__tablename__ = 'student'id = Column(Integer, primary_key=True, index=True)name = Column(String, index=True, comment="名稱")age = Column(Integer, index=True, comment="年齡")hobby = Column(JSON, comment="愛好")def generate_sql(instance: Student) -> SQLCompiler:columnsmap = {c.name: getattr(instance, c.name) for c in instance.__table__.columns}columns = columnsmap.keys()stmt = text(f"INSERT INTO {instance.__tablename__} ({', '.join(columns)}) VALUES ({', '.join([f":{c}" for c in columns])});").bindparams(**columnsmap)return stmt.compile(dialect=sqlalchemy.dialects.mysql.dialect(), compile_kwargs={"literal_binds": True})

輸出:

ikun = Student(id=1, name="ikun", age=30, hobby=json.dumps(["唱跳", "rap", "籃球"]))
jay = Student(id=1, name="jay", age=26, hobby=json.dumps(["唱歌", "足球"]))
print(generate_sql(ikun)) # INSERT INTO student (id, name, age, hobby) VALUES (1, 'ikun', 30, '["\\u5531\\u8df3", "rap", "\\u7bee\\u7403"]');
print(generate_sql(jay)) # INSERT INTO student (id, name, age, hobby) VALUES (1, 'jay', 26, '["\\u5531\\u6b4c", "\\u8db3\\u7403"]');

如果text() 創建原始SQL文本語句,使用參數占位符 :name, :age, :hobby,bindparams() 將實際值綁定到SQL語句中的占位符,dialect=sqlalchemy.dialects.mysql.dialect() 指定使用MySQL方言。使用這種生成也不需要考慮特殊字符轉義的問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64834.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64834.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64834.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

廬山派K230學習日記2 MicroPython基礎

MicroPython文檔: https://docs.micropython.org/ MicroPython是編程語言 Python3 的精簡高效實現,語法和 Python3 保持一致,但只實現了 Python 標準庫的一小部分,并且經過優化,適用于物聯網 (IoT)、消費電子和嵌入式…

《計算機組成及匯編語言原理》閱讀筆記:p177-p177

《計算機組成及匯編語言原理》學習第 13 天,p177-p177 總結,總計 1 頁。 一、技術總結 1.real mode A programming model where the program has access to the entire capability of the machine, bypassing security and memory management. Useful…

2000-2020年各省財政一般預算支出面板數據

2000-2020年各省財政一般預算支出面板數據 1、時間:2000-2020年 2、來源:國家統計局 3、指標:年份、省份、地方財政一般預算支出 4、范圍:31省 指標解釋:地方財政一般預算支出?是指地方ZF根據預算安排&#xff0…

python小項目:給復制出來的段落前添加星號

給復制出來的段落前添加星號 最終效果二、實現步驟2.1 編寫python腳本2.2 批處理腳本2.3 運行腳本 三、用到知識3.1 pyperclip 模塊 最終效果 說明:復制四段內容(段落實際不做限制),在windows終端輸入 bulletPointAdder&#xff0…

【LeetCode Hot100 二分查找】搜索插入位置、搜索二維矩陣、搜索旋轉排序數組、尋找兩個正序數組的中位數

二分查找 搜索插入位置搜索二維矩陣在排序數組中查找元素的第一個和最后一個位置尋找旋轉排序數組中的最小值搜索旋轉排序數組尋找兩個正序數組的中位數(hard) 搜索插入位置 給定一個排序數組和一個目標值,在數組中找到目標值,并…

24.Java 新特性擴展(重復注解、類型注解)

一、重復注解 1、基本介紹 自從 JDK 5 引入注解以來,注解的使用開始流行,在各個框架中被廣泛使用 不過注解有一個很大的限制,在同一個地方不能多次使用同一個注解 JDK 8 引入了重復注解的概念 2、具體實現 (1)自…

后端java開發路由接口并部署服務器(四)

一、安裝IntelliJ IDEA,安裝包下載 1、官網下載 2、網盤資源 安裝包下載完成后進行傻瓜式下一步安裝就可以了 打開IntelliJ IDEA,輸入網盤資源文件內容 三、漢化處理 插件搜索chinese,就會找到相應的插件安裝重啟軟件即可 四、新建后端j…

Vue.js 表單驗證實戰:一個簡單的登錄頁面

修改日期備注2025.1.2初版 一、前言 Vue.js 學習第一天——學會一個帶有簡單表單驗證的登錄頁面。通過這個項目,會對 Vue.js 的核心概念有了更深入的理解,加深掌握如何運用 Vue 的一些強大特性來實現動態交互和數據處理。 二、項目的基本結構 首先&a…

MySQL 鎖那些事

Q1 : MySQL有哪些鎖,功能是什么,如何項目中使用?Q2 : 行鎖是如何實現的?什么情況下會使用行鎖?Q3 : 四種事務隔離形式的行鎖有什么不一樣?讀未提交讀提交可重復讀串行 Q4 : MySQL 的讀寫都是怎樣加鎖的?Q5 : 需要注意什么? Q1 : MySQL有哪些鎖,功能是什么,如何項目中使用…

國產文本編輯器EverEdit - 批量轉碼轉換行符

1 批量轉碼&轉換行符 1.1 應用場景 如果用戶批量在Windows編輯文件,要上傳到異構系統,如:Linux,則需要批量轉換編碼和換行符,此時可以使用EverEdit的批量轉碼功能。 1.2 使用方法 選擇主菜單文檔 -> 批量轉碼…

Java實現下載excel模板,并實現自定義下拉框

GetMapping("excel/download")ApiOperation(value "模板下載")public void getUserRecordTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream response.getOutputStream();InputStream…

成立一家無人機培訓機構需要哪些基礎配置

成立一家無人機培訓機構,需要一系列基礎配置來確保教學質量、學員安全以及機構的正常運營。以下是根據公開發布的信息整理出的關鍵基礎配置: 一、場地配置 1. 飛行場:提供一個安全、寬敞的室外飛行環境,面積最好大于三千平米&…

交換機性能詳解

1. 背板帶寬 只有模塊化交換機(擁有可擴展插槽,可靈活改變端口數量)才有這個概念,固定端換機是沒有這個概念的。并且固定端換機的背板容量和交換容量大小是相等的。 背板帶寬是交換機的總數據處理能力,由硬件架構設…

讀“將計算性能調高到極致的基點秘訣”的嘗試

看到一篇文章,說最近閱讀LAMMPS源碼,悟出了很多道理。在計算性能優化這塊,源代碼作者很多寫法我最初不以為意,后來發現是作者有意為之,就是為了把計算性能優化到極致。做計算仿真軟件,也特別需要注意這些吧…

Gitea代碼倉服務搭建

特點與優勢 輕量級:Gitea是一個輕量級的Git服務,提供了快速、穩定的代碼托管和協作開發環境。它資源占用低,適合在資源受限的環境中運行。易于安裝和部署:Gitea提供了簡單易用的安裝和部署方式,支持多種安裝方式,包括二進制文件、Docker容器等,并提供了詳細的文檔和配置…

leetcode hot 小偷

class Solution(object):def rob(self, nums):""":type nums: List[int]:rtype: int"""# 使用動態規劃,把之前的給保存起來ans[0,nums[-1]]for i in range(1,len(nums)):ans.append(max(ans[-1],ans[-2]nums[-1*i-1]))return ans[-1]…

端口被占用

端口8080被占用 哈哈哈,我是因為后端項目跑錯了,兩個項目后端名稱太像了; (1)netstat -aon | findstr 8080,找到占用8080端口的進程號,獲取對應的進程號pid; (2&#…

文件本地和OSS上傳

這里寫目錄標題 前端傳出文件后端本地存儲阿里云OSS存儲上傳Demo實現上傳ConfigurationProperties 前端傳出文件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>上傳文件</title> </head&g…

[人工智能] 結合最新技術:Transformer、CLIP與邊緣計算在提高人臉識別準確率中的應用

隨著人工智能的快速發展&#xff0c;特別是深度學習和自然語言處理領域的革命性技術&#xff0c;越來越多的前沿技術被應用于人臉識別中。Transformer架構、CLIP模型以及邊緣計算的結合&#xff0c;正成為提升人臉識別準確率和應用效能的關鍵技術路徑。特別是在多樣化場景下&am…

Python的*args和**kwargs

參考 總結&#xff1a; &#xff08;1&#xff09;*args用于在函數中處理傳遞的位置參數序列&#xff1b; &#xff08;2&#xff09;**kwargs則用于處理傳遞的關鍵字參數字典。 &#xff08;3&#xff09;示例&#xff1a; def complex_function(first, *args, **kwargs)…