尝试用 python 查询两个 mysql 数据库并将结果写入 google 表(每天自动更新)

Trying to query two mysql databases with python and write the result in google sheets (auto-update every day)

我的数据分为两个 mysql 具有相同结构的数据库。

我想做的是编写一个 python 脚本,从两个数据库中提取和附加数据,将其存储在变量或文本文件中(比方说 somefile.csv),然后另一个脚本从 variable/text 文件中获取数据并通过 google sheets api 在 google sheets 中导入它。需要注意的是,我的数据每天都在变化,我也希望两个脚本都自动更新(运行 每天并获取更新的数据,第一个重写 csv,第二个重写 google sheet 使用来自 csv 的新数据)。

这可能吗?

我目前拥有的是:

第一个脚本:

from mysql.connector import connect, Error

username = "user"
password = "pass"

connection_1 = connect(
    host="hostaddress",
    user=username,
    password=password,
    database="databasename"
)

connection_2 = connect(
    host="hostaddress",
    user=username,
    password=password,
    database="databasename"
)

cursor_1 = connection_1.cursor()
cursor_2 = connection_2.cursor()

q1 = open('query_db1.sql', 'r')
query1 = q1.read()
q1.close()

q2 = open('query_db2.sql', 'r')
query2 = q2.read()
q2.close()

try:
    with connection_1:
        with cursor_1:
            cursor_1.execute(query_1)
            for row in cursor_1.fetchall():
                print(row)
    with connection_2:
        with cursor_2:
            cursor_2.execute(query2)
            for row in cursor_2.fetchall():
                print(row)
except Error as e:
    print(e)

我在这个脚本中面临的两个问题是:

  1. 如何将执行查询的数据存储在一个变量中或将其保存到一个文件中?
  2. 如何让那个脚本每天查询数据库并更新存储的信息?

在第二个脚本中,我有

from googleapiclient.discovery import build
from google.oauth2 import service_account

SERVICE_ACCOUNT_FILE = 'googleapicredentials.json'
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

creds = None
creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

SAMPLE_SPREADSHEET_ID = 'SHEET_ID'

service = build('sheets', 'v4', credentials=creds)

request = sheet.values().update(spreadsheetId=SAMPLE_SPREADSHEET_ID,
                            range="Sheet1!A1", valueInputOption="USER_ENTERED", body={"values":"somefile.csv"}).execute()

同样,我不知道如何每天更新该脚本。

尽管我使用基于 javascript.

的 google 应用程序脚本,但我每天都在多个项目上这样做

您可以将触发器(如计时作业)设置为 运行 您选择的时间表上的功能。触发器在脚本编辑器中设置。寻找沙漏图标。或者,您可以根据脚本中的代码设置触发器。

/**
 * Creates time-driven triggers
 *
 * https://developers.google.com/apps-script/reference/script/clock-trigger-builder
 */
function createTimeDrivenTriggers() {
  // Trigger every day at 04:00AM CT.
  ScriptApp.newTrigger('csvDaily')
      .timeBased()
      .everyDays(1)
      .atHour(4)
      .create();
}

这是一个代码片段,显示了用于访问我的 MySQL 数据库的应用脚本代码,我删除了用户名和密码:

const MAXROWS = 10000;
const HOST = '65.60.34.202';
const PORT = '3306';
const USERNAME = '';
const PASSWORD = '';
const DATABASE = 'agustafa_barnes';
const DB_TYPE = 'mysql';

function getL2s() {
  var L2s = [];
  try {
    var fullConnectionString = 'jdbc:' + DB_TYPE + '://' + HOST + ':' + PORT;
    var conn = Jdbc.getConnection(fullConnectionString, USERNAME, PASSWORD);
    var stmt = conn.createStatement();
    stmt.execute('USE ' + DATABASE);
    var query = "SELECT * FROM L2s WHERE !IsDeleted ORDER BY TeamTL";
    var rs = stmt.executeQuery(query);

    while (rs.next()) {
      L2s.push([rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5)]);
    }
    rs.close();
    stmt.close();
  } catch (e) {
        console.log(e, e.lineNumber);
  }

  return L2s;
}

因此,如果无法访问您的数据库 table(我和我的公司有同样的问题),也许您可​​以设置一些数据提取例程。我们公司有数百个,需要基本授权。我发出一个网络请求,然后我可以将数据写入 google 工作表或我自己的 MySQL 数据库。这是我们使用的示例 URL:

https://app.yourdomain.com/datadumper/report.ashx?reportid=5107&startDate=2021-04-08&endDate=2021-04-08&bu=3&currentuser=john.agusta&__action=Export#

然后您可以按如下方式编写应用脚本:

/*
https://modjeska.us/csv-google-sheets-basic-auth/
https://redfin.engineering/when-importdata-isnt-good-enough-retrieving-csv-files-behind-basic-auth-with-a-google-apps-script-6c563f3328c5
cm9iZXJ0Om9sZHRpcmVz -- this is a base 64-encoded string of the form

<username>:<password>. In this case, the value represents the username 'robert' and the password 'oldtires', so the string prior to encoding is: robert:oldtires

this site can be used to create a base 64-encoded string:

https://www.base64encode.net/


*/

const auth = '';

VAR URL = "https://app.yourdomain.com/datadumper/report.ashx?reportid=5107&startDate=2021-04-08&endDate=2021-04-08&bu=3&currentuser=john.agusta&__action=Export#";
var csvContents = getCSVContents(URL);
var parsedContents = parseCsvResponse(csvContents, true);

function getCSVContents(csvUrl) {
// request the CSV
    var resp = UrlFetchApp.fetch(csvUrl, {
        headers: {
            // use basic auth
            'Authorization': 'Basic ' + auth
        }
    });
  return resp.getContentText();
}

// parse the CSV response
function parseCsvResponse(csvString, ignoreHeaders) {
  var retArray = [];
  var numCols = 0;
  var i = 0;
  var j = 0;
  var line = "";
  var strLines = csvString.split(/\n/g);
  if (ignoreHeaders) {
    strLines.shift();
  }
  var lenLines = strLines.length;  
  for (i = 0; i < lenLines; i++) {
    line = strLines[i];
    if (line != '') {
      retArray.push(line.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/));
      numCols = retArray[i].length;
      // remove outer double quotes
      for (j = 0; j < numCols; j++) {
        retArray[i][j] = retArray[i][j].replace(/^"|"$/g, '');
      }
    }
  }
  return retArray;
}

回答

1.如何将执行查询的数据存储在一个变量中或将其保存到一个文件中?

使用模块pickle。保存和加载变量非常容易。

2。如何让那个脚本每天查询数据库并更新存储的信息?

使用模块schedule。一旦你安装了它,你可以定义一个文件的执行如下:

import schedule
import time

def job():
    print("I'm working...")

schedule.every().day.at("10:30").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

参考文献: