SQLAlchemy玩转MySQL JSON数据类型

传统的关系型数据库在处理结构化数据方面表现出色,但面对半结构化或非结构化数据时,它们的能力就显得有些力不从心。为了解决这一问题,MySQL引入了对JSON数据类型的支持。

SQLAlchemy作为Python领域中一个强大的ORM(对象关系映射)工具,为我们提供了一种优雅的方式来操作这些JSON数据,它提供了一种高层的Pythonic抽象,以方便地与数据库进行交互。

在本篇文章中,将通过示例演示如何使用SQLAlchemy来操作MySQL中的JSON数据类型,同时也给出对应的SQL语句

创建数据库引擎和会话

from sqlalchemy import create_engine, Column, Integer, String, JSON, select, func, update, text
from sqlalchemy.orm import sessionmaker, declarative_base

Base = declarative_base()
engine = create_engine('mysql+pymysql://user:password@localhost/dbname')
Session = sessionmaker(bind=engine)
session = Session()

创建表

class Document(Base):
    __tablename__ = 'document'
    doc_id = Column(Integer, primary_key=True, autoincrement=True)
    doc_name = Column(String(255), nullable=False)
    extra = Column(JSON) # 额外信息,JSON格式

Base.metadata.create_all(engine)
CREATE TABLE document (
    doc_id INT AUTO_INCREMENT PRIMARY KEY,
    doc_name VARCHAR(255) NOT NULL,
    extra JSON -- 额外信息,JSON格式
);

插入数据

documents = [
    Document(doc_name='Document 1', extra={"author": "John Doe", "keywords": ["SQL", "Database"]}),
    Document(doc_name='Document 2', extra={"author": "Jane Smith", "keywords": ["MySQL", "JSON"]}),
    Document(doc_name='Document 3', extra={"author": "Michael Johnson", "keywords": ["Data Analysis", "Python"]}),
    Document(doc_name='Document 4', extra={"author": "Emily Davis", "keywords": ["Programming", "Algorithms"]}),
    Document(doc_name='Document 5', extra={"author": "Chris Wilson", "keywords": ["Web Development", "JavaScript"]}),
    Document(doc_name='Document 6', extra={"author": "Amanda Brown", "keywords": ["Machine Learning", "AI"]}),
    Document(doc_name='Document 7', extra={"author": "Daniel Lee", "keywords": ["Cloud Computing", "AWS"]}),
    Document(doc_name='Document 8', extra={"author": "Sophia Martinez", "keywords": ["Cybersecurity", "Networks"]}),
    Document(doc_name='Document 9', extra={"author": "William Taylor", "keywords": ["Mobile Apps", "iOS", "Android"]}),
    Document(doc_name='Document 10', extra={"author": "Olivia Anderson", "keywords": ["Big Data", "Hadoop", "Spark"]})
]
session.add_all(documents)
session.commit()
INSERT INTO document (doc_name, extra) VALUES
('Document 1', '{"author": "John Doe", "keywords": ["SQL", "Database"]}'),
('Document 2', '{"author": "Jane Smith", "keywords": ["MySQL", "JSON"]}'),
('Document 3', '{"author": "Michael Johnson", "keywords": ["Data Analysis", "Python"]}'),
('Document 4', '{"author": "Emily Davis", "keywords": ["Programming", "Algorithms"]}'),
('Document 5', '{"author": "Chris Wilson", "keywords": ["Web Development", "JavaScript"]}'),
('Document 6', '{"author": "Amanda Brown", "keywords": ["Machine Learning", "AI"]}'),
('Document 7', '{"author": "Daniel Lee", "keywords": ["Cloud Computing", "AWS"]}'),
('Document 8', '{"author": "Sophia Martinez", "keywords": ["Cybersecurity", "Networks"]}'),
('Document 9', '{"author": "William Taylor", "keywords": ["Mobile Apps", "iOS", "Android"]}'),
('Document 10', '{"author": "Olivia Anderson", "keywords": ["Big Data", "Hadoop", "Spark"]}');

查询

# 查询文档表中的数据以及额外信息中的作者
stmt = (
    select(Document)
    .where(Document.extra['author'] == 'Sophia Martinez')
)
result = session.execute(stmt).scalars().all()
for row in result:
    print(row.doc_id, row.doc_name, row.extra)
SELECT document.*,extra->'$.author'
FROM document
WHERE extra->'$.author'='Sophia Martinez';

替换整个JSON对象

# 替换文档ID为1的整个extra
stmt = (
    update(Document).
    where(Document.doc_id == 1).
    values({
        Document.extra: {"author": "John Doe2", "keywords": ["SQL2", "Database2"]}
    })
)
session.execute(stmt)
session.commit()
UPDATE document
SET extra = '{"author": "John Doe2", "keywords": ["SQL2", "Database2"]}'
WHERE doc_id = 1;

更新某个键对应的值

# 更新文档ID为1的作者
stmt = (
    update(Document).
    where(Document.doc_id == 1).
    values(extra=func.JSON_SET(Document.extra, '$.author', 'New Author'))
)
session.execute(stmt)
session.commit()
UPDATE document
SET extra = JSON_SET(extra, '$.author', 'New Author')
WHERE doc_id = 1;

新增键值对

# 为文档ID为1添加新的字段
stmt = (
    update(Document).
    where(Document.doc_id == 1).
    values({
        Document.extra: func.JSON_SET(Document.extra, '$.new_field', 'new_value')
    })
)
session.execute(stmt)
session.commit()
UPDATE document
SET extra = JSON_SET(extra, '$.new_field', 'new_value')
WHERE doc_id = 1;

删除键值对

# 从文档ID为1的extra字段中删除new_field
stmt = (
    update(Document).
    where(Document.doc_id == 1).
    values({
        Document.extra: func.JSON_REMOVE(Document.extra, '$.new_field')
    })
)
session.execute(stmt)
session.commit()
UPDATE document
SET extra = JSON_REMOVE(extra, '$.new_field')
WHERE doc_id = 1;

添加数组中元素

# 给keywords数组末尾添加一个元素
stmt = (
    update(Document).
    where(Document.doc_id == 1).
    values({
        Document.extra: func.JSON_SET(
            Document.extra,
            '$.keywords',
            func.JSON_ARRAY_APPEND(
                func.JSON_EXTRACT(Document.extra, '$.keywords'),  # 提取现有的keywords数组
                '$',
                'New Keyword'  # 要添加的新关键词
            )
        )
    })
)
session.execute(stmt)
session.commit()
UPDATE document
SET extra = JSON_SET(extra, '$.keywords', JSON_ARRAY_APPEND(extra->'$.keywords', '$', 'New Keyword'))
WHERE doc_id = 1;

删除数组中元素

# 删除keywords数组中的第一个元素
stmt = (
    update(Document).
    where(Document.doc_id == 1).
    values({
        Document.extra: func.JSON_SET(
            Document.extra,
            '$.keywords',
            func.JSON_REMOVE(func.JSON_EXTRACT(Document.extra, '$.keywords'), '$[0]')
        )
    })
)
session.execute(stmt)
session.commit()
UPDATE document
SET extra = JSON_SET(extra, '$.keywords', JSON_REMOVE(extra->'$.keywords', '$[0]'))
WHERE doc_id = 1;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值