- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近我设置了一个 Flask POST 端点,通过 Impyla 模块将数据写入 Impala DB。
环境:CentOS 上的 Python 3.6.5。
Impala版本:impalad版本2.6.0-cdh5.8.0
api.py:
from flask import Flask, request, abort, Response
from flask_cors import CORS
import json
from impala.dbapi import connect
import sys
import re
from datetime import datetime
app = application = Flask(__name__)
CORS(app)
conn = connect(host='datanode2', port=21050,
user='user', database='testdb')
@app.route("/api/endpoint", methods=['POST'])
def post_data():
# if not request.json:
# abort(400)
params = request.get_json(force=True) # getting request data
print(">>>>>> ", params, flush=True)
params['log_time'] = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
# params['page_url'] = re.sub(
# '[^a-zA-Z0-9-_*.]', '', re.sub(':', '_', params['page_url']))
try:
cursor = conn.cursor()
sql = "INSERT INTO table ( page_title, page_url, log_time, machine, clicks, id ) VALUES (%s, %s, %s, %s, %s, %s)"
values = (params['page_title'], params['page_url'], params['log_time'],
params['machine'], params['clicks'], params['id'])
print(">>>>>> " + sql % values, file=sys.stderr, flush=True)
cursor.execute(sql, values)
print(
f">>>>>> Data Written Successfully", file=sys.stderr, flush=True)
return Response(json.dumps({'success': True}), 201, mimetype="application/json")
except Exception as e:
print(e, file=sys.stderr, flush=True)
return Response(json.dumps({'success': False}), 400, mimetype="application/json")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5008, debug=True)
请求.py:
import requests as r
url = "http://123.234.345.456:30001/"
# url = "https://stackoverflow.com/questions/ask"
res = r.post('http://localhost:5008/api/endpoint',
json={
"page_title": "Home",
"page_url": url,
"machine": "Mac OS",
"clicks": 16,
"id": "60cd1d79-eda7-44c2-a4ec-ffdd5d6ac3db"
}
)
if res.ok:
print(res.json())
else:
print('Error!')
我使用 python api.py
运行 Flask api,然后使用 python req.py
进行测试。
flask 服务器出现此错误:
>>>>>> {'page_title': 'Home', 'page_url': 'http://123.234.345.456:30001/', 'machine': 'Mac OS', 'clicks': 16, 'id': '60cd1d79-eda7-44c2-a4ec-ffdd5d6ac3db'}
>>>>>> INSERT INTO table ( page_title, page_url, log_time, machine, clicks, id ) VALUES (Home, http://123.234.345.456:30001/, 2018-12-12 16-14-04, Mac OS, 16, 60cd1d79-eda7-44c2-a4ec-ffdd5d6ac3db)
AnalysisException: Syntax error in line 1:
..., 'http://123.234.345.456'2018-12-12 16-14-04'0001/', ...
^
Encountered: INTEGER LITERAL
Expected: AND, AS, ASC, BETWEEN, CROSS, DESC, DIV, ELSE, END, FOLLOWING, FROM, FULL, GROUP, HAVING, ILIKE, IN, INNER, IREGEXP, IS, JOIN, LEFT, LIKE, LIMIT, NOT, NULLS, OFFSET, OR, ORDER, PRECEDING, RANGE, REGEXP, RIGHT, RLIKE, ROWS, THEN, UNION, WHEN, WHERE, COMMA, IDENTIFIER
CAUSED BY: Exception: Syntax error
这个错误有点烦人:
我尝试直接在 impala-shell 中插入 sql 命令并且它有效。
当 page_url 是唯一参数时,它也可以正常工作。
所以这是某种条件字符转义问题?我通过使用一些正则表达式调整 url 设法绕过了这个问题(取消注释第 27 - 28 行)。但这真的很烦人,我不想因此而清理我的数据。
当我检查其他人的试验时,认为在每个插入值中添加一对引号会起作用。但是,当使用字符串格式时,我该如何执行此操作,并且它必须在 cursor.execute(sql, value)
之前进行?
最佳答案
经过一番努力,并得到 Parameter substitution issue #317 的 @Scratch'N'Purr 和 @msafiullah 的大力帮助,我设法让它发挥作用。这有点复杂,所以我将发布完整的文档代码:
错误原因:通过 Impyla API 出现冒号转义问题。
解决方案:使用自定义的转义函数来处理数据,并采用sql注入(inject)(Python的字符串格式化方式来替换参数)而不是标准的Python DB API,例如: cursor.execute(sql,值)
。
api.py:
from flask import Flask, request, abort, Response
from flask_cors import CORS
import json
from impala.dbapi import connect
from impala.util import _escape
import sys
from datetime import datetime
import six
app = application = Flask(__name__)
CORS(app)
conn = connect(host='datanode2', port=21050,
user='user', database='testdb')
def parameterize(value): # by msafiullah
if value is None:
return "NULL"
elif isinstance(value, six.string_types):
return "'" + _escape(value) + "'"
else:
return str(value)
@app.route("/api/endpoint", methods=['POST'])
def post_data():
if not request.json:
abort(400)
params = request.get_json(force=True) # getting request data
print(">>>>>> ", params, flush=True)
params['log_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
cursor = conn.cursor()
sql = 'INSERT INTO table ( page_title, page_url, log_time, machine, clicks, id ) VALUES ( CAST({} AS VARCHAR(64)), {}, {}, CAST({} AS VARCHAR(32)) , {}, CAST({} AS VARCHAR(32)))'\
.format(parameterize(params['page_title']), parameterize(params['page_url']), parameterize(params['log_time']), parameterize(params['machine']), params['clicks'], parameterize(params['id']))
print(">>>>>> " + sql, file=sys.stderr, flush=True)
cursor.execute(sql)
print(
f">>>>>> Data Written Successfully", file=sys.stderr, flush=True)
return Response(json.dumps({'success': True}), 201, mimetype="application/json")
except Exception as e:
print(e, file=sys.stderr, flush=True)
return Response(json.dumps({'success': False}), 400, mimetype="application/json")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5008, debug=True)
req.py 与 Question 相同。
表
架构:
CREATE TABLE if not exists table (
id VARCHAR(36),
machine VARCHAR(32),
clicks INT,
page_title VARCHAR(64),
page_url STRING,
log_time TIMESTAMP
);
Flask 的服务器输出:
>>>>>> {'page_title': 'Home', 'page_url': 'http://123.234.345.456:30001/', 'machine': 'Mac OS', 'clicks': 16, 'id': '60cd1d79-eda7-44c2-a4ec-ffdd5d6ac3db'}
>>>>>> INSERT INTO table ( page_title, page_url, log_time, machine, clicks, id ) VALUES ( CAST('Home' AS VARCHAR(64)), 'http://123.234.345.456:30001/', '2018-12-14 17:27:29', CAST('Mac OS' AS VARCHAR(32)) , 16, CAST('60cd1d79-eda7-44c2-a4ec-ffdd5d6ac3db' AS VARCHAR(32)))
>>>>>> Data Written Successfully
127.0.0.1 - - [14/Dec/2018 17:27:29] "POST /api/endpoint HTTP/1.1" 201 -
在 Impala-shell 内,select * from table
将给出:
+----------------------------------+--------+--------------+------------+----------------------------------------------------------------------+---------------------+
| id | machine | clicks | page_title | page_url | log_time |
+----------------------------------+--------+--------------+------------+----------------------------------------------------------------------+---------------------+
| 60cd1d79-eda7-44c2-a4ec-ffdd5d6a | Mac OS | 16 | Home | http://123.234.345.456:30001/ | 2018-12-14 17:27:29 |
+----------------------------------+--------+--------------+------------+----------------------------------------------------------------------+---------------------+
基本上,只有数字(例如INT
类型)不需要经过parameterize()
清理/转义过程。其他类型,例如 VARCHAR
、CHAR
、STRING
、TIMESTAMP
(因为冒号)应正确转义为通过 Impyla API 安全插入。
关于python - Impyla 从 Flask 插入 SQL : Syntax error (Identifier Binding),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53739063/
当我使用 Python/Impyla 在 Impala 中执行 SQL 语句时,我只是收到一个异常,其中包含一条通用错误消息,如“”Operation is in ERROR_STATE”。如何获得有
我提到了 How to use variables in SQL statement in Python? 但无法得到答案。 我正在尝试您的建议,但出现此错误 - :( tbl_nm = 'EMPLO
如果我在连接中指定端口,我正在使用 impyla 0.9.0 conn = impala.dbapi.connect(host='n1', port=21000) 我会得到以下错误 Traceback
我正在用 Python 编写一些 ETL 流程,其中部分流程使用 Hive。 Cloudera 的 impyla 客户端,根据 documentation , 适用于 Impala 和 Hive。 根
我已经安装了 impyla 及其依赖项 this指导。安装似乎是成功的,因为现在我可以在 Anaconda 文件夹(64 位 Anaconda 4.1.1 版本)中看到文件夹 "impyla-0.13
我在 Windows 上使用 impyla 库时遇到问题 我安装了impyla库 pip 安装 impyla 在python代码中导入impyla库时出现错误 from impala.dbapi im
有谁知道我在哪里可以找到此 impyla 示例中提到的 numba impala 扩展 (numba.ext.impala):https://github.com/cloudera/impyla/tr
我在一台 W8 机器上,我使用 Python(Anaconda 发行版)连接到我们 Hadoop 集群中的 Impala,使用Impyla 包。我们的 hadoop 集群通过 Kerberos 进行保
我在一台 W7 机器上,我使用 Python(Anaconda 发行版)通过 Impyla 包连接到我们 Hadoop 集群中的 Impala。我的公司最近添加了 Kerberos,这最终破坏了我的现
我正在使用 impyla 模块连接到 kerberized hadoop 集群。我想访问 hiveserver2/hive 但我收到以下错误: test_conn.py from impala.dba
我正在尝试使用 impyla 和以下代码连接到 impala: from impala.dbapi import connect conn = connect(host='host_name.com'
尝试创建到 HiveServer 的连接时出现以下错误 Traceback (most recent call last): File "/Users/user_name/Desktop/ABC
我试图在 Hadoop 上对 Cloudera Impala 的 python impyla 查询中的字符进行转义,但似乎没有任何效果。模板语法没有转义(对于数据库 API 来说不寻常。) curso
最近我设置了一个 Flask POST 端点,通过 Impyla 模块将数据写入 Impala DB。 环境:CentOS 上的 Python 3.6.5。 Impala版本:impalad版本2.6
我是一名优秀的程序员,十分优秀!