python - 如何替换 json 字段 /w null,插入 PostgreSQL 数据库
问题描述
我已经查看了这里讨论的一些选项,但我没有发现最适合我的情况。我将它加载到数据库并且该字段设置为 SMALLINT,但是如果尚未更新,则 api 会为例如月落时间提供“无月落”。还是我想多了,有一个更简单的解决方案?
这是我当前的代码:
#!/usr/bin/env python3
import requests
import json
from decouple import config
from db import *
from datetime import datetime, timedelta, date
def insert_weather():
insert_query = '''INSERT INTO public.weather (date, temp, dwpt, rhum, prcp, wdir, wspd, pres, updte)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)
ON CONFLICT(date)
DO UPDATE SET
temp = excluded.temp, dwpt = excluded.dwpt, rhum = excluded.rhum, prcp = excluded.prcp, wdir = excluded.wdir, wspd = excluded.wspd, pres = excluded.pres, updte = excluded.updte;'''
valuestoinset = (dt, temp, dwpt, rhum, precip, winddir, wspd, pres, updte)
cur.execute(insert_query, valuestoinset)
def insert_astra():
insert_query = '''INSERT INTO public.weather_date(
date, sunrise, sunset, moonrise, moonset, moon_phase, max_temp_f, min_temp_f, totalprecip_in, updte)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT(date)
DO UPDATE SET
sunrise = excluded.sunrise, sunset = excluded.sunset, moonrise = excluded.moonrise, moonset = excluded.moonset, moon_phase = excluded.moon_phase, max_temp_f = excluded.max_temp_f, min_temp_f = excluded.min_temp_f, totalprecip_in = excluded.totalprecip_in, updte = excluded.updte;'''
valuestoinset = (date, sunrise, sunset, moonrise, moonset,
moon_phase, max_temp_f, min_temp_f, totalprecip_in, updte)
cur.execute(insert_query, valuestoinset)
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)
# Set Date values
hr = 0
a = 0
curr_hr = datetime.now().hour
end_date = date.today()
start_date = date.today() - timedelta(1)
# Set API values
ak = config('ak')
city = config('city')
# Loop through dates
for single_date in daterange(start_date, end_date):
histurl = 'https://api.weatherapi.com/v1/history.json?key=' + \
ak + '&q=' + city + '&dt=' + single_date.strftime("%Y-%m-%d")
r = requests.get(histurl)
wjson = json.loads(r.text)
# Insert the astral data for that day
date = wjson['forecast']['forecastday'][0]['date']
sunrise = wjson['forecast']['forecastday'][0]['astro']['sunrise']
sunset = wjson['forecast']['forecastday'][0]['astro']['sunrise']
moonrise = wjson['forecast']['forecastday'][0]['astro']['moonrise']
moonset = wjson['forecast']['forecastday'][0]['astro']['moonset']
moon_phase = wjson['forecast']['forecastday'][0]['astro']['moon_phase']
max_temp_f = wjson['forecast']['forecastday'][0]['day']['maxtemp_f']
min_temp_f = wjson['forecast']['forecastday'][0]['day']['mintemp_f']
totalprecip_in = wjson['forecast']['forecastday'][0]['day']['totalprecip_in']
updte = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
insert_astra()
# Loop through the 24 hours of the day
for i in wjson['forecast']['forecastday'][0]['hour']:
updte = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
a += 1
dt = i['time']
time = datetime.strptime(i['time'][11:16], '%H:%M').time()
temp = i['temp_f']
dwpt = i['dewpoint_f']
rhum = i['humidity']
precip = i['precip_in']
winddir = i['wind_dir']
wspd = i['wind_mph']
pres = i['pressure_mb']
if datetime.strptime(dt, '%Y-%m-%d %H:%M') >= datetime.combine(end_date, time):
break
insert_weather()
# Commit to DB
conn.commit()
print(a, "record(s) inserted successfully into table")
解决方案
检查 JSON 是否包含No moonset
并将其替换为None
. 然后将其转换为NULL
存储在数据库中的时间。
moonset = wjson['forecast']['forecastday'][0]['astro']['moonset']
if moonset == 'No moonset':
moonset = None
推荐阅读
- r - 有人可以解释 R 的基本方法吗?
- firebase - Firestore 如何为交叉路口构建数据
- android - Android 相当于 setAudioAttributes() for MediaPlayer on API 低于 21
- javascript - 在 P5.js 中的网格内旋转对象
- ruby-on-rails - 如何创建具有表实例的数据库?
- javascript - Angularjs 中的 HTML 加载
- python-3.x - 多个消费者线程从队列中抓取相同的项目
- signal-processing - 如何使用 bins_per_octave 而非 12 在 librosa 中计算和可视化 CQT?
- swift - 切换选项卡视图后移动的 Swift 滚动视图标签
- android - 显示 AlertDialog 时暂停活动