【发布时间】:2020-07-17 02:25:10
【问题描述】:
我正在尝试使用 Flask、SQLAlchemy 和 PostgreSQL/psycopg2 将来自 Internet 的数据快速加载到表中。我和一位同事发生了轻微的争吵。我们称他为“爸爸”。爸爸争辩说,由于可能存在 SQL 注入,我们无法执行原始 SQL 查询。我认为我们可以,如果它可能是格式化的,这很难做到,通常应该使用 ORM。下面的例子在我看来是一个足够简单的问题。
# Flask-SQLAlachemy
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
server = Flask(__name__)
server.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
server.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://...'
db = SQLAlchemy(server)
@server.route('/<column>')
def index(column):
result = db.session.execute("SELECT" + column + "from item_profit")
return render_template('index.html', data=result)
基本上有人可以将任何原始 SQL 插入列并返回该表。 有关其他简单注射,请参阅此 link。 我看到了这个 SO answer (参见第二个答案),这似乎暗示格式正确的字符串不会导致 SQL 注入。他们的代码如下所示:
result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})
爸爸说很多公司的 DBA 阻止其他部门拥有执行权限,即他们无法使用
result = db.session.execute("...")
我认为这是因为他们担心普通用户不知道如何正确格式化它。那是对的吗?并不是执行 SQL 查询会导致 SQL 注入,而是 不正确 格式的执行查询会导致 SQL 注入。这就是人们说使用 ORM 的原因,因为它始终确保格式正确的查询。这是正确的想法吗? ORM 系统只是在幕后执行。如果执行查询是一个注入问题,那么即使是 ORM 也无法使用。哎呀,连SQL都不能用,对吧?我希望在某些情况下使用原始 SQL,因为我们可能要处理庞大的数据集,其中处理速度是一个主要因素,而 ORM 则要慢得多。
然后我的后续问题是,将 CSV 加载到 SQL 数据库中同时最小化原始 SQL 的最佳方法是什么?爸爸使用 PgAdmin 导入将 CSV 导入到 postgres(节省了在 psql 中写出导入的大量时间)。我知道另一种方法是使用 pandas pandas.Dataframe.to_sql() 方法,但我不认为为此引入 pandas 似乎是这里最好的设计。我通常使用 ORM,但我不确定是否有一种快速获取 CSV 的方法。假设我有一个表格的 csv,Product,有两列,Name 和 Cost。为了在 ORM 中实现这一点,我将执行以下操作:
...
db = SQLAlchemy(app)
class Product(db.Model):
__tablename__ = 'product'
name = db.Column(db.String)
cost = db.Column(db.Double)
但是,我又回到了将 CSV 导入 python 以加载到表中的问题。有来自_csv('')的熊猫。我想我也可以打开文件本身并循环遍历它。类似的东西
for record in csv_file:
product = Product(name=..., cost=...)
db.session.add(product)
db.session.commit()
有没有更好的方法? ORM 是否有办法加载 CSV,同时允许我在大多数时间避免使用原始 SQL?
【问题讨论】:
标签: python sqlalchemy