尝试用 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)
我在这个脚本中面临的两个问题是:
- 如何将执行查询的数据存储在一个变量中或将其保存到一个文件中?
- 如何让那个脚本每天查询数据库并更新存储的信息?
在第二个脚本中,我有
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¤tuser=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¤tuser=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)
参考文献:
我的数据分为两个 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)
我在这个脚本中面临的两个问题是:
- 如何将执行查询的数据存储在一个变量中或将其保存到一个文件中?
- 如何让那个脚本每天查询数据库并更新存储的信息?
在第二个脚本中,我有
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¤tuser=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¤tuser=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)