溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Pandas中讀取sql腳本

發(fā)布時間:2021-01-21 14:26:11 來源:億速云 閱讀:328 作者:Leah 欄目:開發(fā)技術

這篇文章將為大家詳細講解有關如何在Pandas中讀取sql腳本,文章內(nèi)容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

讀取方法:

from io import StringIO
import pandas as pd
import re

def read_sql_script_all(sql_file_path, quotechar="'") -> (str, dict):
  insert_check = re.compile(r"insert +into +`?(\w+?)`?\(", re.I | re.A)
  with open(sql_file_path, encoding="utf-8") as f:
    sql_txt = f.read()
  end_pos = -1
  df_dict = {}
  while True:
    match_obj = insert_check.search(sql_txt, end_pos+1)
    if not match_obj:
      break
    table_name = match_obj.group(1)
    start_pos = match_obj.span()[1]+1
    end_pos = sql_txt.find(";", start_pos)
    tmp = re.sub(r"\)( values |,)\(", "\n", sql_txt[start_pos:end_pos])
    tmp = re.sub(r"[`()]", "", tmp)
    df = pd.read_csv(StringIO(tmp), quotechar=quotechar)
    dfs = df_dict.setdefault(table_name, [])
    dfs.append(df)
  for table_name, dfs in df_dict.items():
    df_dict[table_name] = pd.concat(dfs)
  return df_dict

參數(shù):

  • sql_file_path:sql腳本的位置

  • quotechar:腳本中字符串是單引號還是雙引號,默認使用單引號解析

返回:

一個字典,鍵是表名,值是該表對應的數(shù)據(jù)所組成的datafream對象

下面我測試讀取下面這個sql腳本:

如何在Pandas中讀取sql腳本

其中的表名是index_test

df_dict = read_sql_script_all("D:/tmp/test.sql")
df = df_dict['index_test']
df.head(10)

結果:

如何在Pandas中讀取sql腳本

可以看到能順利的直接從sql腳本中讀取數(shù)據(jù)生成datafream。

當然上面寫的方法是一次性讀取整個sql腳本的所有表,結果為一個字典(鍵為表名,值為datafream)。但大部分時候我們只需要讀取sql腳本的某一張表,我們可以改造一下上面的方法:

def read_sql_script_by_tablename(sql_file_path, table_name, quotechar="'") -> (str, dict):
  insert_check = re.compile(r"insert +into +`?(\w+?)`?\(", re.I | re.A)
  with open(sql_file_path, encoding="utf-8") as f:
    sql_txt = f.read()
  end_pos = -1
  dfs = []
  while True:
    match_obj = insert_check.search(sql_txt, end_pos+1)
    if not match_obj:
      break
    start_pos = match_obj.span()[1]+1
    end_pos = sql_txt.find(";", start_pos)
    if table_name != match_obj.group(1):
      continue
    tmp = re.sub(r"\)( values |,)\(", "\n", sql_txt[start_pos:end_pos])
    tmp = re.sub(r"[`()]", "", tmp)
    df = pd.read_csv(StringIO(tmp), quotechar=quotechar)
    dfs.append(df)
  return pd.concat(dfs)

參數(shù):

  • sql_file_path:sql腳本的位置

  • table_name:被讀取的表名

  • quotechar:腳本中字符串是單引號還是雙引號,默認使用單引號解析

返回:

該表所對應的datafream對象

讀取代碼:

df = read_sql_script_by_tablename("D:/tmp/test.sql", "index_test")
df.head()

結果:

如何在Pandas中讀取sql腳本

將sql腳本轉換為sqlite格式并通過本地sql連接讀取

在寫完上面的方法后,我又想到另一種解決思路,就是將sql腳本轉換成sqlite語法的sql語句,然后直接加載。各種類型的數(shù)據(jù)庫的sql語句變化較大,下面的方法僅針對SQLyog導出的mysql腳本測試通過,如果是其他的數(shù)據(jù)庫,可能下面的方法仍然需要微調(diào)。最好是先自行將sql腳本轉換為sqlite語法的sql語句后,再使用我寫的方法加載。

加載sql腳本的方法:

from sqlalchemy import create_engine
import pandas as pd
import re


def load_sql2sqlite_conn(sqltxt_path):
  create_rule = re.compile("create +table [^;]+;", re.I)
  insert_rule = re.compile("insert +into [^;]+;", re.I)
  with open(sqltxt_path, encoding="utf-8") as f:
    sqltxt = f.read()
  engine = create_engine('sqlite:///:memory:')
  pos = -1
  while True:
    match_obj = create_rule.search(sqltxt, pos+1)
    if match_obj:
      pos = match_obj.span()[1]
      sql = match_obj.group(0).replace("AUTO_INCREMENT", "")
      sql = re.sub("\).+;", ");", sql)
      engine.execute(sql)
    match_obj = insert_rule.search(sqltxt, pos+1)
    if match_obj:
      pos = match_obj.span()[1]
      sql = match_obj.group(0)
      engine.execute(sql)
    else:
      break
  tablenames = [t[0] for t in engine.execute(
    "SELECT tbl_name FROM sqlite_master WHERE type='table';").fetchall()]
  return tablenames, engine.connect()

參數(shù):

sql_file_path:sql腳本的位置

返回:

兩個元素的元組,第一個元素是表名列表,第二個元素是sqlite內(nèi)存虛擬連接

測試讀?。?/p>

tablenames, conn = load_sql2sqlite_conn("D:/tmp/test.sql")
tablename = tablenames[0]
print(tablename)
df = pd.read_sql(f"select * from {tablename};", conn)
df

結果:

如何在Pandas中讀取sql腳本

關于如何在Pandas中讀取sql腳本就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI