python写入一年时间到系统交易日表,区分交易日非交易日,效果如下图

1.需要用到的临时表和目标表
1.1 创建临时表
create table TEMPDATA_AA
(
c1 VARCHAR2(30),
c2 VARCHAR2(30),
c3 VARCHAR2(30),
c4 VARCHAR2(30),
c5 VARCHAR2(30),
c6 VARCHAR2(30),
c7 VARCHAR2(30),
c8 VARCHAR2(30),
c9 VARCHAR2(30),
c10 VARCHAR2(30),
n1 NUMBER(9),
n2 NUMBER(9),
n3 NUMBER(9),
n4 NUMBER(9),
n5 NUMBER(9),
n6 NUMBER(9),
n7 NUMBER(9),
n8 NUMBER(9),
n9 NUMBER(9),
n10 NUMBER(9)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
1.2 创建目标表
create table T_XTJYR
(
naturalday NUMBER(8),
tradeday NUMBER(8),
year NUMBER(4),
quarter NUMBER(1),
month NUMBER(2),
week NUMBER(1),
year_month NUMBER(6),
year_weeknum NUMBER(6),
weeknum NUMBER(2),
is_workday NUMBER(1)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
alter table T_XTJYR
add unique (NATURALDAY)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
2.准备和插入数据
import cx_Oracle
import pandas as pd
con = cx_Oracle.connect('scott/123@localhost:1521/orcl',encoding='utf-8')
sql = ''' SELECT * FROM tempdata_aa a '''
cur = con.cursor()
cur.execute(sql)
df = pd.read_sql(sql,con)
print(df)
from calendar import Calendar
def array_to_list(array):
if not isinstance(array, (list, )):
return [array]
else:
list_y = []
for item in array:
list_y += array_to_list(item)
return list(set(list_y))
if __name__ == '__main__':
b = Calendar(firstweekday=0).yeardatescalendar(2021,12)
c = array_to_list(b)
print(c,len(c))
import requests
import json
def catch_url_from_baidu(calcultaion_year, month):
headers = {
"Content-Type": "application/json;charset=UTF-8"
}
param = {
"query": calcultaion_year + "年" + month + "月",
"resource_id": "39043",
"t": "1604395059555",
"ie": "utf8",
"oe": "gbk",
"format": "json",
"tn": "wisetpl",
"cb": ""
}
r = requests.get(url="https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php",
headers=headers, params=param).text
month_data = json.loads(r)["data"][0]["almanac"]
not_work_day = []
for one in month_data:
date_str=one["year"] + "-" + one["month"] + "-" + one["day"]
c = int(dt.strptime(date_str,'%Y-%m-%d').strftime('%Y%m%d'))
if (one["cnDay"] == '日' or one["cnDay"] == '六'):
if ('status' in one):
if (one["status"] == "2"):
continue
else:
not_work_day.append(c)
continue
else:
not_work_day.append(c)
continue
if ('status' in one and one["status"] == "1"):
not_work_day.append(c)
return not_work_day
def print_info(calcultaion_year):
calculation_month = ["2", "5", "8", "11"]
list_not_workday=[]
for one_month in calculation_month:
a = catch_url_from_baidu(calcultaion_year, one_month)
list_not_workday.append(a)
list_not_workday = array_to_list(list_not_workday)
return list_not_workday
def is_workday(num1):
if num1 in list_not_workday:
return 0
else:
return 1
if __name__ == '__main__':
calcultaion_year = "2020"
print_info(calcultaion_year)
print(list_not_workday)
print(len(list_not_workday))
from calendar import Calendar
def insert_date(year):
""" 先写入一年的自然日到临时表 tempdata_aa 中 """
date_array = Calendar(firstweekday=0).yeardatescalendar(year,12)
date_list = array_to_list(date_array)
con = cx_Oracle.connect('scott/123@localhost:1521/orcl',encoding='utf-8')
j = 0
for i in date_list:
if int(i.year) == year:
i = int(i.strftime('%Y%m%d'))
is_work = is_workday(i)
try:
sql =f'''INSERT INTO tempdata_aa(n1,n2) VALUES({i},{is_work})'''
con.cursor().execute(sql)
con.commit()
j += 1
print('第{}次插入数据成功'.format(j))
except Exception as e:
print('第{}次数据插入失败:{}'.format(j, e))
continue
if 'con' in dir():
con.close()
if __name__ == '__main__':
year = 2021
insert_date(year)
try:
con = cx_Oracle.connect('scott/123@localhost:1521/orcl',encoding='utf-8')
sql =f''' INSERT INTO t_xtjyr
(naturalday,
tradeday,
YEAR,
quarter,
MONTH,
week,
year_month,
year_weeknum,
weeknum)
SELECT to_char(n1, 'yyyymmdd') AS naturalday,
tradeday,
to_char(n1, 'yyyy') AS YEAR,
to_char(n1, 'q') AS quarter,
to_char(n1, 'mm') AS MONTH,
to_char(n1, 'd') - 1 AS week,
to_char(n1, 'yyyymm') AS year_month,
to_char(n1, 'yyyyww') AS year_weeknum,
to_char(n1, 'ww') AS weeknum
FROM (SELECT to_date(a2.n1, 'yyyymmdd') AS n1,
MAX(a1.n1) AS tradeday,
a2.n2
FROM tempdata_aa a2
LEFT JOIN tempdata_aa a1
ON a1.n1 <= a2.n1
AND a1.n2 = 1
GROUP BY a2.n1, a2.n2
ORDER BY a2.n1)
con.cursor().execute(sql)
con.commit()
except Exception as e:
print('数据插入失败:{}'.format(e))
finally:
if 'con' in dir():
con.close()
注意:
1.如果是第一次时开始使用节假日,一定要先把 list_not_workday列表先插入所有的数据,然后再检查临时表 tempdata_aa
2.表t_test 提供了2000年——2021的数据,也可以直接使用,当然后续每年12月份更新次年的数据就要使用上面的逻辑