Google Flex App Engine 未写入云 SQL 数据库
Google Flex App Engine not writing to Cloud SQL database
编辑:已解决,见底部
我正在开展一个项目,该项目从 Meraki 扫描 API 接收数据并将该 JSON 数据写入云 SQL 数据库。该代码最初可以很好地写入本地 MySQL 数据库,但我已经尝试了大约 800 种不同的配置和调整,但似乎没有任何效果。我在 Flex App Engine 和 Cloud SQL 之间建立了连接,数据库和表都在那里,但没有 writing/INSERT 语句 运行。这是一个使用 SQLAlchemy 的 Flask 应用程序(NOT Flask_SQLAlchemy)
Meraki 扫描 API 文档供参考:
https://documentation.meraki.com/MR/Monitoring_and_Reporting/Scanning_API
from api import app
from sqlalchemy import create_engine
from datetime import datetime, timedelta
engine = create_engine(app.config.get('database_uri'))
class Events(object)
@staticmethod
def add(event):
connection = engine.connect()
for observation in event["observations"]:
try:
connection.execute("""INSERT INTO events (
apMac,
apTags,
apFloors,
clientMac,
ipv4,
ipv6,
seenTime,
seenEpoch,
ssid,
rssi,
manufacturer,
os,
lat,
lng,
unc,
x,
y
) VALUES (
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
)""", (
event.get("apMac", None),
",".join(event.get("apTags", [])),
",".join(event.get("apFloors", [])),
observation.get("clientMac", None),
observation.get("ipv4").strip("/") if observation.get("ipv4") is not None else None,
observation.get("ipv6", None),
observation.get("seenTime", None),
observation.get("seenEpoch", None),
observation.get("ssid", None),
observation.get("rssi", None),
observation.get("manufacturer", None),
observation.get("os", None),
observation.get("location", {}).get("lat", None),
observation.get("location", {}).get("lng", None),
observation.get("location", {}).get("unc", None),
observation.get("location", {}).get("x", None) if observation.get("location", {}).get("x", None) != [] else None,
observation.get("location", {}).get("y", None) if observation.get("location", {}).get("y", None) != [] else None,
))
except:
pass
connection.close()
return "Added"
那是事件 class 具有添加到它的功能。
这是另一个处理提供验证器的脚本,因此 Meraki 将开始 POST JSON 数据到页面:
from flask import request
from api import app
from api.models import Events
@app.route('/', methods=['GET'])
def events_get():
return str(app.config.get("validator"))
@app.route('/', methods=['POST'])
def events_post():
data = request.json
if data["secret"] != app.config.get("secret"):
return
Events.add(data["data"])
return "."
数据库 URI 设置为(我已经尝试使用 mysql 以及 mysql+pymysql):
mysql+mysqldb://<user>:<pw>@/<database>?unix_socket=/cloudsql/<instance connection name>
我正在接收 POST,但云端没有数据 SQL。任何帮助是极大的赞赏。谢谢。
解决方案:我不得不在 Cloud SQL 上恢复到 MySQL 5.6。与 MySQL 的 ALLOW_INVALID_DATES 标志相结合修复了此问题并将时间保留为日期时间。
尝试按照建议启用 SQLAlchemy 日志记录 here:
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
现在,我看到的第二件事是您捕获了所有异常但什么都不做。
一般来说,这被认为是一种不好的做法。
除此之外,它可能会给您一个线索,说明为什么您没有插入任何数据。
删除 try...except
或添加异常日志记录以查看发生了什么 - 在这里可能对您有所帮助。
最后,你可以尝试使用事务方式,不确定。
来自 SQLAlchemy connection docs 的示例:
trans = connection.begin()
try:
r1 = connection.execute(table1.select())
connection.execute(table1.insert(), col1=7, col2='this is some data')
trans.commit()
except:
trans.rollback()
raise
更新:
另外,不确定你的语法 execute("INSERT .... VALUES (%s, %s, ...), (value1, value2))
是否有效,但如果你说它适用于本地服务器,那么你可能可以忽略这个。
我在官方文档中看到的是
engine.execute("insert into users values (?, ?)", 1, "john")
,
即问号 ?
而不是 %s
和展开的参数,而不是列表。
更新2:
还要确保实际调用了 Events.add
,将 print
放在各处以查看值。
在您的情况下,可能是 secret
值不匹配。
编辑:已解决,见底部
我正在开展一个项目,该项目从 Meraki 扫描 API 接收数据并将该 JSON 数据写入云 SQL 数据库。该代码最初可以很好地写入本地 MySQL 数据库,但我已经尝试了大约 800 种不同的配置和调整,但似乎没有任何效果。我在 Flex App Engine 和 Cloud SQL 之间建立了连接,数据库和表都在那里,但没有 writing/INSERT 语句 运行。这是一个使用 SQLAlchemy 的 Flask 应用程序(NOT Flask_SQLAlchemy)
Meraki 扫描 API 文档供参考: https://documentation.meraki.com/MR/Monitoring_and_Reporting/Scanning_API
from api import app
from sqlalchemy import create_engine
from datetime import datetime, timedelta
engine = create_engine(app.config.get('database_uri'))
class Events(object)
@staticmethod
def add(event):
connection = engine.connect()
for observation in event["observations"]:
try:
connection.execute("""INSERT INTO events (
apMac,
apTags,
apFloors,
clientMac,
ipv4,
ipv6,
seenTime,
seenEpoch,
ssid,
rssi,
manufacturer,
os,
lat,
lng,
unc,
x,
y
) VALUES (
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
)""", (
event.get("apMac", None),
",".join(event.get("apTags", [])),
",".join(event.get("apFloors", [])),
observation.get("clientMac", None),
observation.get("ipv4").strip("/") if observation.get("ipv4") is not None else None,
observation.get("ipv6", None),
observation.get("seenTime", None),
observation.get("seenEpoch", None),
observation.get("ssid", None),
observation.get("rssi", None),
observation.get("manufacturer", None),
observation.get("os", None),
observation.get("location", {}).get("lat", None),
observation.get("location", {}).get("lng", None),
observation.get("location", {}).get("unc", None),
observation.get("location", {}).get("x", None) if observation.get("location", {}).get("x", None) != [] else None,
observation.get("location", {}).get("y", None) if observation.get("location", {}).get("y", None) != [] else None,
))
except:
pass
connection.close()
return "Added"
那是事件 class 具有添加到它的功能。 这是另一个处理提供验证器的脚本,因此 Meraki 将开始 POST JSON 数据到页面:
from flask import request
from api import app
from api.models import Events
@app.route('/', methods=['GET'])
def events_get():
return str(app.config.get("validator"))
@app.route('/', methods=['POST'])
def events_post():
data = request.json
if data["secret"] != app.config.get("secret"):
return
Events.add(data["data"])
return "."
数据库 URI 设置为(我已经尝试使用 mysql 以及 mysql+pymysql):
mysql+mysqldb://<user>:<pw>@/<database>?unix_socket=/cloudsql/<instance connection name>
我正在接收 POST,但云端没有数据 SQL。任何帮助是极大的赞赏。谢谢。
解决方案:我不得不在 Cloud SQL 上恢复到 MySQL 5.6。与 MySQL 的 ALLOW_INVALID_DATES 标志相结合修复了此问题并将时间保留为日期时间。
尝试按照建议启用 SQLAlchemy 日志记录 here:
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
现在,我看到的第二件事是您捕获了所有异常但什么都不做。
一般来说,这被认为是一种不好的做法。
除此之外,它可能会给您一个线索,说明为什么您没有插入任何数据。
删除 try...except
或添加异常日志记录以查看发生了什么 - 在这里可能对您有所帮助。
最后,你可以尝试使用事务方式,不确定。 来自 SQLAlchemy connection docs 的示例:
trans = connection.begin()
try:
r1 = connection.execute(table1.select())
connection.execute(table1.insert(), col1=7, col2='this is some data')
trans.commit()
except:
trans.rollback()
raise
更新:
另外,不确定你的语法 execute("INSERT .... VALUES (%s, %s, ...), (value1, value2))
是否有效,但如果你说它适用于本地服务器,那么你可能可以忽略这个。
我在官方文档中看到的是
engine.execute("insert into users values (?, ?)", 1, "john")
,
即问号 ?
而不是 %s
和展开的参数,而不是列表。
更新2:
还要确保实际调用了 Events.add
,将 print
放在各处以查看值。
在您的情况下,可能是 secret
值不匹配。