最新要闻
- 两批次食品不符合国家标准上黑榜 全球快资讯
- 俩石柱子被五菱一下子撞飞 附近店家感慨:此乃神车
- 米哈游去年赚了161亿!网友:够再开发十个《原神》了
- 每日快报!时代变了!未来18个月内 传奇瑞等大量国产车企将进入英国市场
- 世界速讯:越南因罕见高温遭遇“停电危机”:佳能等企业轮流停电
- 全球视讯!多种口味:和路雪经典大梦龙多口味雪糕16支88元发车
- 甘肃省加快推进交通项目建设 每日快播
- 《暗黑4》第一件“军帽”在韩服现身 官方证实:最强欧皇诞生 属性无敌
- 苹果回应Mac Pro弃用AMD显卡:压根就不适配_天天微速讯
- VIP体验卡到期!高考后饭菜的反差让人猝不及防:从“吃啥有啥”变“有啥吃啥”
- 今日报丨windows图片查看器修复(windows图片查看器)
- 国家助学贷款累计发放超4000亿元 惠及2000多万名学生
- 曝苹果开发Vision Pro更便宜版本:屏幕、处理器会缩水|世界看热讯
- A卡降价太狠 NVIDIA坐不住:RTX 4060将提前上市 2399买吗?|焦点
- 汽车人险胜蜘蛛侠
- 产销两旺 新能源车消费涌热潮
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Python工具箱系列(三十五) 全球新消息
前文使用了SQLAlchemy的Core层来实现数据库、表与数据的CRUD。初步体现出了SQLAlchemy的优势。但ORM的特点没有充分地表现出来。下面的代码则从Python的类出现,生成表结构,并且进行数据的CRUD操作。
【资料图】
from sqlalchemy import (Column, DateTime, Float, ForeignKey, Integer, MetaData, String, Table, create_engine, text)from sqlalchemy.orm import Session, registry, relationshipfrom sqlalchemy_utils.functions import create_database, database_existsimport randomimport datetimefrom sqlalchemy import selectconfigure_pg = {"user": "postgres", "password": "88488848", "dns": "192.168.0.155", "port": 5432, "prefix": "postgresql+psycopg2", "postfix": "" }configure_mssql = {"user": "sa", "password": "88488848", "dns": "192.168.0.155", "port": 1433, "prefix": "mssql+pymssql", "postfix": "?charset=utf8" }configure_mysql = {"user": "root", "password": "88488848", "dns": "192.168.0.155", "port": 3306, "prefix": "mysql+mysqlconnector", "postfix": "" }config = {"mssql": configure_mssql, "mysql": configure_mysql, "postgresql": configure_pg}database_name = "sensordb"table_sensor_location = "sensor_location_orm"table_sensor_data = "sensor_data_orm"mapper_registry = registry()Base = mapper_registry.generate_base()class Sensor(Base): __tablename__ = table_sensor_location id = Column(Integer, primary_key=True, autoincrement=False) location = Column(String(30)) def __repr__(self): return f"Sensor(id={self.id!r}, location={self.location!r}"class SensorData(Base): __tablename__ = table_sensor_data id = Column(Integer, primary_key=True, autoincrement=False) sensor_id = Column(Integer, ForeignKey(f"{table_sensor_location}.id")) sensor = relationship("Sensor") area = Column(String(30)) pm25 = Column(Float) timestamp = Column(DateTime) def __repr__(self): return f"SensorData(id={self.id!r}, pm25={self.pm25!r})"def linkdb(targetstr): """ 连接不同的数据库 Args: targetstr (string): 数据库名称 Returns: engine: 用于后续的数据库连接 """ if targetstr in config.keys(): item = config[targetstr] connectstring = f"{item["prefix"]}://{item["user"]}:{item["password"]}@{item["dns"]}:{item["port"]}/{database_name}{item["postfix"]}" engine = create_engine(connectstring, echo=True, future=True) # 如果数据库不存在,则创建之 if not database_exists(engine.url): create_database(engine.url) return enginedef gen_sensorinfo(connector): # 向sensor_location_orm插入传感器记录 sensor1 = Sensor(id=1, location="floor") sensor2 = Sensor(id=2, location="wall") session = Session(connector) session.add(sensor1) session.add(sensor2) session.commit()def gen_sensordata(connector): # 向sensor_data_orm插入测量数据 session = Session(connector) currenttime = datetime.datetime.now() # 向sensor_data_orm插入多条记录 for index in range(10): currenttime = currenttime+datetime.timedelta(seconds=1) sensordata = SensorData(id=index, sensor_id=index % 2 + 1, area="xian", pm25=random.uniform(0, 300), timestamp=currenttime) session.add(sensordata) session.flush() session.commit()def query_demo(connector): """ 查询示例代码 Args: connector (engine): 数据库连接 """ session = Session(connector) # 查询传感器信息 stmt = select(Sensor).where(Sensor.id == 2) print(stmt) result = session.execute(stmt) for sensor_obj in result.scalars(): print(sensor_obj.location) # 查询传感器数据 stmt = select(SensorData).order_by(SensorData.sensor_id) print(stmt) result = session.execute(stmt) for sensordata_obj in result.scalars(): print(sensordata_obj.pm25,sensordata_obj.timestamp) # join stmt = select(SensorData.id,SensorData.pm25, Sensor.location).join(SensorData.sensor).order_by(SensorData.pm25) for row in session.execute(stmt): print(row)# 依次连接多个数据库。从而验证代码的一致性for dbname in config.keys(): con = linkdb(dbname) # 创建数据库 mapper_registry.metadata.create_all(con) # 创建传感器信息 gen_sensorinfo(con) # 创建传感器数据 gen_sensordata(con) # 查询示例 query_demo(con)
ORM编程的一个好处就是不用写SQL语句,而以面向对象的思维方式来看数据库。正如前文所说,ORM将类与数据库的表一一对应。我们定义两个类。
◆Sensor类。保存传感器本身的信息。
◆SensorData类-保存传感器测量出来的数据。
这两个类均继续SQLAlchemy提供的Base类。虽然也可以自行定义类与表的映射关系,但最方便的仍然是直接继承Base类。两个类的写法类似,均需要定义主键,同时在SensorData类定义了外键形成Sensor与SensorData的ONE-TO-MANY的关系如下图所示:
类Sensor中的repr是为了方便输出信息用。类SensorData中的relationship定义了与Sensor的关联,后续在ORM基于JOIN的查询中起作用。
定义好Sensor与SensorData类后,直接使用mapper_registry.metadata.create_all(con)就可以创建与两个类对应的数据库。代码分别在mysql/mssql/postgresql等数据库中同时建立sensordb数据库与对应的两个表。
随后gen_sensorinfo创建2个Sensor类的实例,然后当作记录插入到表中。gen_sensordata创建10个模拟数据,并且当作记录插入表中,如下图所示:
在整个创建数据库/表/记录的过程中,全程没有SQL语句出现。随后使用query_demo演示查询的能力。
stmt = select(Sensor).where(Sensor.id == 2)print(stmt)
以上代码能够输出对应的SQL语句如下:
SELECT sensor_location_orm.id, sensor_location_orm.locationFROM sensor_location_ormWHERE sensor_location_orm.id = %(id_1)s
这些代码就是SQLAlchemy在后台实际运行的SQL语句。更为复杂的基于表关联的查询如下所示:
stmt = select(SensorData.id,SensorData.pm25, Sensor.location).join(SensorData.sensor).order_by(SensorData.pm25)for row in session.execute(stmt): print(row)
以上语句对表sensor_data_orm进行查询,同时基于sensor_id关联到sensor_location_orm表,将传感的位置信息输出。形成的查询结果如下所示:
(1, 52.030998649965355, "wall")(0, 52.33204928632623, "floor")(6, 59.39568057249285, "floor")(2, 73.41761802578553, "floor")(9, 77.12459935499986, "wall")(4, 119.62669535658156, "floor")(5, 154.50858896768042, "wall")(7, 165.03277721842784, "wall")(3, 186.1637895876464, "wall")(8, 288.3729395365834, "floor")
由于语句中要求order_by(SensorData.pm25),所以id不是连续的,但pm列是从小到大排列。同时传感器的位置信息也显示出来。从示例代码来看,对于数据库的操作完成类似于对类的操作,查询方式也非常简单,不用关心SQL的实现,体现了ORM编程的强大威力。不过SQLAlchemy虽然好,但设计之初的目标是针对关系型数据库的,NOSQL数据库的支持不足。部分数据库(例如clickhouse等)自行提供了对SQLAlchemy的支持。
关键词:
Python工具箱系列(三十五) 全球新消息
vue使用 elementUI中el-upload的遇到的问题总结
【新华解读】可转债退市机制逐步完善 未来或迎来“宽进宽出”市场生态_全球新动态
两批次食品不符合国家标准上黑榜 全球快资讯
俩石柱子被五菱一下子撞飞 附近店家感慨:此乃神车
米哈游去年赚了161亿!网友:够再开发十个《原神》了
每日快报!时代变了!未来18个月内 传奇瑞等大量国产车企将进入英国市场
世界速讯:越南因罕见高温遭遇“停电危机”:佳能等企业轮流停电
全球视讯!多种口味:和路雪经典大梦龙多口味雪糕16支88元发车
物联网开源操作系统简介 天天快资讯
Jenkins + Docker 一键自动化部署 Spring Boot 项目,步骤齐全,少走坑路! 全球微动态
甘肃省加快推进交通项目建设 每日快播
《暗黑4》第一件“军帽”在韩服现身 官方证实:最强欧皇诞生 属性无敌
苹果回应Mac Pro弃用AMD显卡:压根就不适配_天天微速讯
VIP体验卡到期!高考后饭菜的反差让人猝不及防:从“吃啥有啥”变“有啥吃啥”
今日报丨windows图片查看器修复(windows图片查看器)
解读投顾新规(一)| 扭转投顾“产品化”倾向 引导行业回归服务本源
【读财报】基金发行透视:年内发行规模同比下降15% 鹏扬、国融基金产品发行失败_全球快资讯
国家助学贷款累计发放超4000亿元 惠及2000多万名学生
曝苹果开发Vision Pro更便宜版本:屏幕、处理器会缩水|世界看热讯
A卡降价太狠 NVIDIA坐不住:RTX 4060将提前上市 2399买吗?|焦点
汽车人险胜蜘蛛侠
产销两旺 新能源车消费涌热潮
读改变未来的九大算法笔记10_读后总结与感想 播报
动力电池回收赛道不断升温 上市公司积极挖掘新蓝海-环球热推荐
全球速读:女子220斤家人为激励减肥奖6万 已减超20斤:网友鼓励加油
当前速递!显卡不买丐版就亏了?到底该怎么选?
电路中的pnp是什么意思(电路中pn结是什么意思) 世界关注
深度学习应用篇-计算机视觉-OCR光学字符识别[7]:OCR综述、常用CRNN识别方法、DBNet、CTPN检测方法等、评估指标、应用场景
面对英特尔大小核CPU AMD调整CPU供货和价格-每日速递
新华三率先推出私域行业大模型:百业灵犀
大师名团密集来京演出,“演艺之都”绽放国际星光 前沿资讯
白蛋白的功效与作用是什么_白蛋白的功效与作用 世界热点
“双万亿”之城、世界工厂……制造业重镇东莞涌现新动能-全球快看
刀锋战士2迅雷下载链接(刀锋战士2迅雷下载)-当前独家
每日热闻!蓝莓树苗怎么种植盆栽_蓝莓树苗怎么种
如果我是清风我将什么续写句子_如果我是清风我将
ps哪个版本最好用2020(ps哪个版本最好用)_全球时快讯
现在满族人的姓氏汉化 满族人的姓氏都有哪些-全球信息
世界观点:电信营业厅电话费_电信营业厅电话
全球热头条丨珠峰被救女士拒绝支付救人费用引争议 登山公司公布遇险原因
引用《道德经》,谈大国分歧,Sam Altman 最新演讲:AI 安全始于足下_环球报道
天天讯息:英媒:经济学家预测美国需至少加息两次才能平息通胀
热推荐:铃木天语sx4二手车(铃木天语sx4隐藏功能是什么?)
从“国家宝藏”到“何以中国”,总台文博类综艺这样创新实践|文化和自然遗产日
【天天播资讯】【技术积累】Java中的泛型【一】
天天亮点!HBase的数据结构原理与使用
Xilinx GTH 简介 ,CoaXpress FPGA PHY 部分-天天短讯
左偏树-环球观点
世界最新:ChatGPT只讲这25个笑话!有90%重复 网友:幽默是人类最后的尊严
环球速讯:火车站按摩椅现大量虫子 商家:每天都有打扫 很少有这种情况
焦点滚动:福建多地为何纷纷成立这一机构?
聚焦:希捷4TB机械硬盘史低 仅售288元
社交综艺为何能成爆款_世界百事通
芯片的战争
这些年,祝勇的“纸上故宫”都在写些什么?|文化观察 天天讯息
List 接口及其常用方法 全球即时看
文心一言 VS 讯飞星火 VS chatgpt (38)-- 算法导论5.4 2题 全球新要闻
吢丕的另一个情侣网名(吢)
环球短讯!最后一艘潜艇电影国语版百度云(最后一艘潜艇电影国语版)
镁条在空气中燃烧发出耀眼的白光(镁条在空气中燃烧)
女朋友不理你怎么办表情包_女朋友不理你怎么办
南京两大厦间现龙卷风:强风至路面闪现火花 每日视点
当前简讯:14代酷睿要来了 英特尔13代酷睿i9包装简化:独特身份消失
预计2025年突破万亿元规模 产学研各方共议储能大赛道
徐州城下城遗址博物馆“上新”
天天热点!金陵十二钗判词及人物(金陵十二钗判词)
每日消息!散水模板工程量怎么计算(算混凝土工程量散水怎么计算)
今日快讯:口腔材料app(口腔材料网)
焦点热议:好高骛远的读音_好高骛远的意思
今日热议:Hbase安装和shell客户端操作
Web安全-渗透测试-信息收集01|全球热文
世界热消息:杯具!上海一小区电动车爆炸起火 家人惨被烧伤:网友吵翻为何电池拿回家充电
莫扎特的一句话(关于莫扎特的话例如说他天真)
世界热点!莫扎特的一句话(关于莫扎特的话例如说他天真)
清远公用品牌IP形象亮相-全球播报
关于铁路计次票、定期票 如何购买使用 环球聚看点
天天视点!多地高温预警 今年618空调没促销降价:还有经销商趁机涨价
龙爸无双100集电视剧免费观看|当前热门
第二届联合国人居大会闭幕 通过“人人享有可负担住房”等决议_百事通
消息!第二届联合国人居大会闭幕 通过“人人享有可负担住房”等决议
中超综合:中超第一阶段结束 上海海港领跑积分榜
中超积分榜:海港领跑三镇仅第8 大连人倒数第一
第34届中国经济新闻奖:21世纪经济报道获评论一等奖、融合报道一等奖 天天精选
全球讯息:武汉到清江画廊旅游攻略_清江画廊旅游攻略
新动态:最美童星长大后惊艳全网!16岁时因“不够性感”被导演刷掉,她霸气怒怼:恶心的猪!
窒息灭火法是指什么_窒息灭火法
全球快资讯:美国旧金山毒品泛滥、暴力犯罪猖獗 市民称正在目睹西方文明崩溃
每日热门:引导资金支持绿色发展 新华碳科技指数发布
这些大胆的古早综艺,真的是不付费就能看的吗? 当前消息
《暗黑破坏神4》差评如潮 跌到5.1分了_世界焦点
最资讯丨蓉火传递启动|“中国民航英雄机组”成员毕楠:当上火炬手,是荣誉也是责任
社区多元化多角度全方位服务新业态新就业群体
以太阳鸟为标志 G985高铁列车因高考火了:网友打卡沾喜气
湖南景区回应游客漂流翻船:第一天开业人多 放水没控制好-即时看
每日一猜6月10日:哪款能重塑眼镜人士新体验 世界快播
热点在线丨7744小游戏盒_7743小游戏
北京铁路:6月15日起,京津城际、京唐城际等线路运行图有调整
五部门联合启动河湖安全保护专项执法行动
全球信息:21个“问界”商标已转让至华为 申请时间为今年3月