Python 和 Pandas 来查询 API 和更新数据库

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 的查询,我觉得我过于复杂了。

谢谢!

Tro*_*y D 5

我看不出您有任何理由在此过程中创建 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)