Google Flex App Engine не пишет в базу данных Cloud SQL - PullRequest
0 голосов
/ 31 мая 2018

РЕДАКТИРОВАТЬ: решено, см. Внизу

Я работаю над проектом, который получает данные из API сканирования Meraki и записывает эти данные JSON в базу данных Cloud SQL.Первоначально код прекрасно записывался в локальную базу данных MySQL, но я пробовал около 800 различных конфигураций и настроек, но ничего не работает.У меня есть связь между Flex App Engine и Cloud SQL, база данных и таблицы есть, но операторы write / INSERT не выполняются.Это приложение Flask, использующее SQLAlchemy ( NOT Flask_SQLAlchemy)

Документация по API сканирования Meraki для справки: 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"

Это класс Event с функциейэто добавляет к этому.Это другой сценарий, который имеет дело с предоставлением валидатора, поэтому Meraki начнет отправлять данные 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, но данные о Cloud SQL отсутствуют.Любая помощь очень ценится.Спасибо.

РЕШЕНИЕ: мне пришлось вернуться к MySQL 5.6 на облачном SQL.Это в сочетании с флагом ALLOW_INVALID_DATES для MySQL исправило это и сохранило время как DateTime.

1 Ответ

0 голосов
/ 31 мая 2018

Попробуйте включить ведение журнала SQLAlchemy, как предложено здесь :

import logging

logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

Теперь, второе, что я вижу, это то, что вы перехватываете ВСЕ исключения и НИЧЕГО не делаете.Это считается плохой практикой в ​​целом.Кроме того, это может дать вам понять, почему вы не вставляете какие-либо данные.Удалите try...except или добавьте ведение журнала исключений, чтобы увидеть, что происходит, - здесь вам может помочь.

Наконец, вы можете попробовать использовать транзакционный подход, не уверен.Пример из Документы по соединению SQLAlchemy :

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 и нераспакованные аргументы, а не список.

UPDATE2 : ТАКЖЕ убедитесь, что Events.add действительно вызван, поместите print s везде, чтобы увидеть значения.В вашем случае это может быть secret несоответствие значения.

...