Mic*_*orn 3 python mysql sqlalchemy pandas
我一直在用 Python 查询一些 API 来单独为一个表创建 CSV。
我想尝试而不是每次都重新创建表,而是使用任何新的 API 数据更新现有表。
目前查询的工作方式,我有一个看起来像这样的表,
由此,我将每个州的郊区复制到每个不同州的 csv 中。
然后使用这个脚本我将它们清理到一个列表中(api 需要 %20 来表示任何空格),
"%20"
#suburbs = ["want this", "want this (meh)", "this as well (nope)"]
suburb_cleaned = []
#dont_want = frozenset( ["(meh)", "(nope)"] )
for urb in suburbs:
cleaned_name = []
name_parts = urb.split()
for part in name_parts:
if part in dont_want:
continue
cleaned_name.append(part)
suburb_cleaned.append('%20'.join(cleaned_name))
Run Code Online (Sandbox Code Playgroud)
然后取每个州的郊区并将它们放入这个 API 以返回一个 csv,
timestr = time.strftime("%Y%m%d-%H%M%S")
Name = "price_data_NT"+timestr+".csv"
url_price = "http://mwap.com/api"
string = 'gxg&state='
api_results = {}
n = 0
y = 2
for urbs in suburb_cleaned:
url = url_price + urbs + string + "NT"
print(url)
print(urbs)
request = requests.get(url)
api_results[urbs] = pd.DataFrame(request.json())
n = n+1
if n == y:
dfs = pd.concat(api_results).reset_index(level=1, drop=True).rename_axis(
'key').reset_index().set_index(['key'])
dfs.to_csv(Name, sep='\t', encoding='utf-8')
y = y+2
continue
print("made it through"+urbs)
# print(request.json())
# print(api_results)
dfs = pd.concat(api_results).reset_index(level=1, drop=True).rename_axis(
'key').reset_index().set_index(['key'])
dfs.to_csv(Name, sep='\t', encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
然后在excel中手动添加州,并合并和清理郊区名称。
# use pd.concat
df = pd.concat([act, vic,nsw,SA,QLD,WA]).reset_index().set_index(['key']).rename_axis('suburb').reset_index().set_index(['state'])
# apply lambda to clean the %20
f = lambda s: s.replace('%20', ' ')
df['suburb'] = df['suburb'].apply(f)
Run Code Online (Sandbox Code Playgroud)
然后最后将它插入到数据库中
engine = create_engine('mysql://username:password@localhost/dbname')
with engine.connect() as conn, conn.begin():
df.to_sql('Price_historic', conn, if_exists='replace',index=False)
Run Code Online (Sandbox Code Playgroud)
领导这种输出
现在,这是一个非常复杂的过程。我很想简化它并使数据库只更新 API 所需的值,并且在获取数据时没有那么复杂。
会喜欢一些关于实现这个目标的有用提示 - 我想我可以对 mysql 数据库进行更新而不是插入或其他什么?并且随着 API 的查询,我觉得我过于复杂了。
谢谢!
我看不出您有任何理由在此过程中创建 CSV 文件。听起来您可以只查询数据,然后直接将其加载到 MySql 表中。你说你是在excel中手动添加状态?这些数据是否无法通过您之前的 api 调用获得?如果没有,您能否找到该信息并将其保存到 CSV,以便您可以通过将其加载到表中并让 Python 为您查找值来自动执行该步骤?
通常,您不会希望每次都覆盖 mysql 表。当您有一个表时,您可以标识唯一标识特定记录的一列或多列,然后为它们创建一个 UNIQUE INDEX。例如,如果您的街道和价格值指定了一个唯一条目,那么您可以在 mysql 中运行:
ALTER TABLE `Price_historic` ADD UNIQUE INDEX(street, price);
Run Code Online (Sandbox Code Playgroud)
在此之后,您的表将不允许基于这些值的重复记录。然后,您可以将数据插入现有表,而不是每次都创建一个新表,并附上在遇到重复时更新或忽略的说明。例如:
final_str = "INSERT INTO Price_historic (state, suburb, property_price_id, type, street, price, date) " \
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s) " \
"ON DUPLICATE KEY UPDATE " \
"state = VALUES(state), date = VALUES(date)"
con = pdb.connect(db_host, db_user, db_pass, db_name)
with con:
try:
cur = con.cursor()
cur.executemany(final_str, insert_list)
Run Code Online (Sandbox Code Playgroud)