Python学习之五_字符串处理生成查询SQL

Posted 济南小老虎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习之五_字符串处理生成查询SQL相关的知识,希望对你有一定的参考价值。

Python学习之五_字符串处理生成查询SQL


前言

昨天想给同事讲解一下获取查询部分表核心列信息的SQL方法
也写好了一个简单文档. 但是感觉不是很优雅. 
最近两三天晚上一直在学习Python. 想将昨天的文档处理成一个工具的方式.
将查询SQL展示出来. 然后再由同事手工检查确认. 增加时间范围等处理
理论上这样能够加快处理速度. 避免过多的拼接过程. 

Python的处理过程

添加三个脚本文件
dbconnection.py 拼接数据库连接字符串使用
gettablesql.py  查询数据库, 获取表SQL使用
getsql.py       接收输入的表名, 打印这个表核心列查询SQL

需要的module主要有
sys,configparser,jaydebeapi
方法比较简单, 本着自学的态度进行学习与使用. 

dbconnection.py

# coding=utf-8

import jaydebeapi
import configparser

config = configparser.ConfigParser()
config.read(\'dbconnection.ini\',encoding=\'utf-8\')
def getconn(dbinstance) :
    jdbcString = config.get(dbinstance,\'jdbcString\')
    driverPath = config.get(dbinstance,\'driverPath\')
    urlString = config.get(dbinstance,\'urlString\')
    userName = config.get(dbinstance,\'userName\')
    passWord = config.get(dbinstance,\'passWord\')
    conn = jaydebeapi.connect(jdbcString,urlString,[userName,passWord],driverPath)
    return conn

gettablesql.py

import dbconnection
import configparser

def gettablesql (configfile,dbinfo,tablename) :

    config = configparser.ConfigParser()
    config.read(configfile,encoding=\'utf-8\')
    conn = dbconnection.getconn(dbinfo)

    getsql = ("""
    SELECT
            LISTAGG ( COLUMN_NAME, \',\')
        FROM
            user_tab_cols 
        WHERE
            table_name = upper( \'"""
    + str(tablename) +
    """\' ) 
            AND column_name NOT LIKE \'%TIME%\' 
            AND column_name NOT LIKE \'%_PT\' 
            AND column_name NOT LIKE \'%_CHT\' 
            AND column_name NOT LIKE \'%_ES\' 
            AND column_name NOT LIKE \'%_EN\' 
            AND column_name NOT LIKE \'%DATE%\' 
        ORDER BY
            COLUMN_NAME ASC 
    """)
    cur = conn.cursor()
    cur.execute(getsql)
    columninfo = cur.fetchall()
    getdatasql=("select " + str(columninfo)[3:-4] + " from  " + str(tablename) + " order by 1 asc" )
    return getdatasql
    cur.close()

调用函数 getsql.py

import gettablesql
import sys

tablename = sys.argv[1]
sql = gettablesql.gettablesql(\'dbconnection.ini\',\'bf\',tablename)
print(sql)

处理的一些说明

1. """ 表示多行字符串. 
2. 字符串建议使用 () 小括号括起来, 便于处理
3. 字符串可以使用 + 的方式进行拼接. 建议可以进行str(xxx)的方式进行显示转换. 
4. str(xxxx)[3:-4] 表示删除前面三个,最后四个字符. 
   这里正好将 oracle listagg 出来的tuple记过的前面三个多语的福浩删除掉了
5. def xxxx : 进行定义函数, return 到被调用函数就可以了. 

字符串处理的一些加深学习

之前一直使用shell 进行字符串的处理
自己也记录了非常多的shell 处理工具的命令和方式.
最近学习python 感觉更简洁和方便. 
需要多学习, 需要保持学习的能力

学习可以使你有离开的能力, 只有这样才不会总被人欺负. 
本文后面的大部分学习自:
https://baijiahao.baidu.com/s?id=1738413163267646541

1. 判断输入字符串的类型

zhaobsh = input("请输入: " )
print(zhaobsh.isalpha())

使用pycharm 可以提示出具体的判断函数
isascii
isspace
isupper
islower

2. 字符串拼接

print(\'-\'.join(zhaobsh))  # 用来指定拼接符号,拼接出一个字符串,效率比+高
print(zhaobsh.center(100, \'*\'))  # 字符串居中,左右填充指定内容
print(zhaobsh.ljust(50, \'*\'))  # 返回一个原字符串左对齐,并使用空格填充至指定长度的新字符串。
                                 如果指定的长度小于原字符串的长度则返回原字符串。
print(zhaobsh.rjust(50, \'*\'))  # 它将原字符串右对齐,并使用空格填充至指定长度,并返回新的字符串。
                                 如果指定的长度小于原字符串长度,则直接返回原字符串。
print(zhaobsh.zfill(50))  # 返回指定长度的字符串,原字符串右对齐,前面填充0。

3. 查找

print(str.count(\'p\'))  # 指定内容,在原str中出现了多少次

print(str.find(\'pip\'))  # 包含pip,则返回开始的索引值,否则返回-1。
print(str.index(\'pip\'))  # 包含pip,则返回开始的索引值,否则返回Exception。

print(str.rfind(\' \'))  # 返回参数字符串在字符串中最后一次出现的位置。没有查询到则返回-1.
print(str.rindex(\' \'))  # 返回参数字符串在字符串中最后一次出现的位置。没有查询到则返回Exception.

4.分隔和替换

print(str.replace(\' \', \'-\'))  # 替换操作,str.replace()函数并不对原有的字符串进行改变。

print(str.partition(\' \'))  # 如果字符串包含指定的分隔符,则返回一个3元的元组,第一个为分隔符左边的子串,第二个为分隔符本身,第三个为分隔符右边的子串。
print(str.rpartition(\' \'))  # 类似于 partition() 方法,只是该方法是从目标字符串的末尾也就是右边开始搜索分割符。

print(str.rsplit(\' \'))  # 如果给出了 maxsplit,则最多进行 maxsplit 次拆分,从 最右边 开始。
print(str.split(\' \'))  # 分割字符串
print(str.splitlines())  # 按照行界符(\'\\r\', \'\\r\\n\', \\n\'等)分隔,返回一个包含各行作为元素的列表,默认不包含行界符。

print(str.lstrip(\'p\'))  # 删除从开头开始指定的字符串,然后返回结果字符串。注意:只能从开头开始
print(str.rstrip(\'p\'))  # 删除 string 字符串末尾的指定字符,默认为空白符,包括空格、换行符、回车符、制表符。
print(str.strip())  # 删除前后的指定字符,默认是空格

5.大小写操作

print(str.capitalize())  # 第一个字母大写,对中文无效
print(str.lower())  # 字母转为小写,只对英语有效
print(str.casefold())  # 字母转为小写,所有语言都有效,例如:德语
print(str.upper())  # 字母全部转为大写,英语有效
print(str.swapcase())  # 将字符串中的英文字母大小写互换,并返回修改后的字符串。
print(str.title())  # 将字符串中的每个单词首字母大写,其余字母小写,并返回新的字符串。

6. 判断内容

print(str.startswith(\'pip\'))  # 判断是否以pip为开头
print(str.endswith(\'office\'))  # 判断str是否以office结尾
print(str.isalnum())  # 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
print(str.isalpha())  # 如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False
print(str.isascii())  # 如果字符串为空或字符串中的所有字符都是 ASCII,则返回 True,否则返回 False。
print(str.isdecimal())  # 如果字符串中的所有字符都是十进制字符,则返回True
print(str.isdigit())  # isdigit函数检测字符串中是否只包含数字字符。若全部是由数字字符组成的字符串,则返回True,否则返回False。isdigit函数没有参数。
print(str.isidentifier())  # 如果字符串是Python中的有效标识符,返回True。如果不是,则返回False。
print(str.islower())  # islower() 方法检测字符串是否由小写字母组成.
print(str.isupper())  # 检测字符串中所有的字母是否都为大写。
print(str.isnumeric())  # 检查字符串中是否只包含数值字符。此方法只适用于Unicode的对象。

print(str.isprintable())  # 如果字符串中的所有字符都可打印或字符串为空,则返回 True,否则返回 False。
print(str.isspace())  # 检测字符串是否只由空白字符组成。
print(str.istitle())  # 检测字符串中所有的单词拼写首字母是否为大写,且其他字母为小写。

7.其他

print(str.maketrans())#此静态方法返回一个 可供 str.translate() 使用的转换对照表。
print(str.translate())
print(str.encode(encoding=\'utf8\', errors=\'strict\'))  # 返回字符串编码后的数据,默认的编码是当前的字符串编码。errors为给定的不同错误处理方法。
print(str.expandtabs())  # 用空格替换\\t符号
print(str.format(content=\'yyds\'))

format_map_dict = \'content\': \'yyds\'
print(str.format_map(format_map_dict))  # str.format_map(mapping) 方法仅适用于字符串格式中可变数据参数来源于字典等映射关系数据时。mapping 会被直接使用而不是复制到一个 dict。

Flink学习之flink sql

🌰 昨天我们学习完Table API后,今天我们继续学SQL,Table API和SQL可以处理SQL语言编写的查询语句,但是这些查询需要嵌入用Java、Scala和python编写的程序中。

🌱flink sql只需要具备 SQL 的基础知识即可,不需要其他编程经验。我的SQL 客户端选择的是docker安装的Flink SQL Click,大家根据自己的需求安装即可。

目录

1. SQL客户端

SQL客户端内置在Flink的版本中,大家只要启动即可,我使用的是docker环境中配置的Flink SQL Click,让我们测试一下:

输入’helloworld’ 看看输出的结果。

SELECT ‘hello world’;

结果如下:说明运行成功!

2. SQL语句

2.1 create

CREATE 语句用于向当前或指定的 Catalog 中注册表、视图或函数。注册后的表、视图和函数可以在 SQL 查询中使用。

CREATE TABLE [IF NOT EXISTS] [catalog_name.][db_name.]table_name
  (
     <physical_column_definition> | <metadata_column_definition> | <computed_column_definition> [ , ...n]
    [ <watermark_definition> ]
    [ <table_constraint> ][ , ...n]
  )
  [COMMENT table_comment]
  [PARTITIONED BY (partition_column_name1, partition_column_name2, ...)]
  WITH (key1=val1, key2=val2, ...)
  [ LIKE source_table [( <like_options> )] ]


-- 例如
CREATE TABLE Orders_with_watermark (
    `user` BIGINT,
    product STRING,
    order_time TIMESTAMP(3),
    WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND 
) WITH (
    'connector' = 'kafka',
    'scan.startup.mode' = 'latest-offset'
);

2.2 drop

DROP 语句可用于删除指定的 catalog,也可用于从当前或指定的 Catalog 中删除一个已经注册的表、视图或函数。

--删除表
DROP TABLE [IF EXISTS] [catalog_name.][db_name.]table_name
--删除数据库
DROP DATABASE [IF EXISTS] [catalog_name.]db_name [ (RESTRICT | CASCADE) ]
--删除视图
DROP [TEMPORARY] VIEW  [IF EXISTS] [catalog_name.][db_name.]view_name
--删除函数
DROP [TEMPORARY|TEMPORARY SYSTEM] FUNCTION [IF EXISTS] [catalog_name.][db_name.]function_name;

2.3 alter

ALTER 语句用于修改一个已经在 Catalog 中注册的表、视图或函数定义。

--修改表名
ALTER TABLE [catalog_name.][db_name.]table_name RENAME TO new_table_name
--设置或修改表属性
ALTER TABLE [catalog_name.][db_name.]table_name SET (key1=val1, key2=val2, ...)
--修改视图名
ALTER VIEW [catalog_name.][db_name.]view_name RENAME TO new_view_name
--在数据库中设置一个或多个属性。若个别属性已经在数据库中设定,将会使用新值覆盖旧值。
ALTER DATABASE [catalog_name.]db_name SET (key1=val1, key2=val2, ...)

2.4 insert

INSERT 语句用来向表中添加行(INTO是追加,OVERWRITE是覆盖)

-- 1. 插入别的表的数据
INSERT  INTO | OVERWRITE  [catalog_name.][db_name.]table_name [PARTITION part_spec] select_statement

-- 2. 将值插入表中 
INSERT  INTO | OVERWRITE  [catalog_name.][db_name.]table_name VALUES [values_row , values_row ...]



-- 追加行到该静态分区中 (date='2019-8-30', country='China')
INSERT INTO country_page_view PARTITION (date='2019-8-30', country='China')
  SELECT user, cnt FROM page_view_source;

-- 追加行到分区 (date, country) 中,其中 date 是静态分区 '2019-8-30';country 是动态分区,其值由每一行动态决定
INSERT INTO country_page_view PARTITION (date='2019-8-30')
  SELECT user, cnt, country FROM page_view_source;

-- 覆盖行到静态分区 (date='2019-8-30', country='China')
INSERT OVERWRITE country_page_view PARTITION (date='2019-8-30', country='China')
  SELECT user, cnt FROM page_view_source;

-- 覆盖行到分区 (date, country) 中,其中 date 是静态分区 '2019-8-30';country 是动态分区,其值由每一行动态决定
INSERT OVERWRITE country_page_view PARTITION (date='2019-8-30')
  SELECT user, cnt, country FROM page_view_source;

2.5 show

show用于列出所有的catalog、database、function等

-- 列出catalog
SHOW CATALOGS;
-- 列出数据库
SHOW DATABASES;
--列出表
SHOW TABLES;
-- 列出视图
SHOW VIEWS;
--列出函数
SHOW FUNCTIONS;
-- 列出所有激活的 module
SHOW MODULES;

3. Window Functions

这里的Window Functions不是指我们sql中的窗口函数,是指处理流数据中特有的窗口操作。

3.1 滚动窗口 TUMBLE

TUMBLE函数把行分配到有固定间隔时间且不重叠的窗口上,滚动窗口在批处理和流处理可以定义在事件时间上,但只有流处理可以定义在处理时间上。

--1. TUMBLE函数的参数
TUMBLE(TABLE data, DESCRIPTOR(timecol), size [, offset ])
-- TABLE:代表数据源
-- DESCRIPTOR(timecol):指时间列
-- size:指窗口大小
-- offset:可增加其他参数,会有特别的意义

-- 2.实例
SELECT window_start, window_end, SUM(price)
  FROM TABLE(
    TUMBLE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES))
  GROUP BY window_start, window_end;

3.2 滑动窗口 HOP

滑动窗口在批处理和流处理中可以定义在事件时间上,但只有流处理可以定义在处理时间上。(数据会有重复)

-- 1. HOP函数的参数
HOP(TABLE data, DESCRIPTOR(timecol), slide, size [, offset ])
-- TABLE:代表数据源
-- DESCRIPTOR(timecol):指时间列
-- slide:指窗口滑动的大小
-- size:指窗口大小
-- offset:可增加其他参数,会有特别的意义

-- 2.实例
SELECT window_start, window_end, SUM(price)
  FROM TABLE(
    CUMULATE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '2' MINUTES, INTERVAL '10' MINUTES))
  GROUP BY window_start, window_end;

3.3 累计窗口 CUMULATE

累计窗口是指在固定窗口内,每隔一段时间触发操作。类似于滚动窗口内定时进行累计操作。

--1. 累计窗口的参数
CUMULATE(TABLE data, DESCRIPTOR(timecol), step, size)
--data: 和时间有关的数据源
--timecol: 时间列,数据的哪些时间属性列应该映射到滚动窗口。
--step: 是指定顺序累积窗口结束之间增加的窗口大小的持续时间。
--size: 是指定累积窗口最大宽度的持续时间。size 必须是 step 的整数倍。
-- offset:可增加其他参数,会有特别的意义


-- 实例
SELECT window_start, window_end, SUM(price)
  FROM TABLE(
    CUMULATE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '2' MINUTES, INTERVAL '10' MINUTES))
  GROUP BY window_start, window_end;

4. 其他函数

处理上述这些,剩下还有的操作都是和我们的SQL语法差不多,就不再阐述:

  • 窗口聚合函数:group by、…
  • 分组聚合函数:count、having、count(distinct xxx)、…
  • over聚合函数:over(partition by xxx order by xxx)、…
  • 内外连接函数:join、left join 、outer join、…
  • limit 函数
  • TOP-N函数: rank()、dense_rank()、row_number()

对以上内容感兴趣的小伙伴可以参考如下链接:

5. 总结

今天学习的sql,和往常不一样的地方在于,以往的sql都是处理的是批数据,而今天学习的flink sql可以处理流数据,流数据随着时间的变化而变化,flink sql可以对流数据进行类似表一样的处理,可以实现大部分DataStream API和DataSet API的功能。

😂还有就是,flink sql中的窗口函数和我们传统的窗口函数不一样,按理来说,我们正常的窗口函数应该叫over聚合函数

6. 参考资料

《Flink入门与实战》
《PyDocs》(pyflink官方文档)
《Kafka权威指南》
《Apache Flink 必知必会》
《Apache Flink 零基础入门》
《Flink 基础教程》

以上是关于Python学习之五_字符串处理生成查询SQL的主要内容,如果未能解决你的问题,请参考以下文章

Django学习之model进阶

python学习之生成器yield

Flink学习之flink sql

Flink学习之flink sql

python学习之生成器(generator)

Python学习之迭代器和生成器