Python 同时使用sqlalchemy和sqlalchemy,为什么安全
我已经在一个烧瓶应用程序,是数据库密集型约4个月的工作。我对python、flask和sqlalchemy非常陌生,但对web和数据库编程非常熟悉 我主要使用核心SQL作为硬数据库,但也使用了ORM。我在核心SQL中使用的主要方法是text()和bindparam()函数,它们通过sqlalchemy方言赋予我数据库独立性 我发现自己不得不混合我的模块导入来获得我想要的东西。这里是一个简单但典型的导入Python 同时使用sqlalchemy和sqlalchemy,为什么安全,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我已经在一个烧瓶应用程序,是数据库密集型约4个月的工作。我对python、flask和sqlalchemy非常陌生,但对web和数据库编程非常熟悉 我主要使用核心SQL作为硬数据库,但也使用了ORM。我在核心SQL中使用的主要方法是text()和bindparam()函数,它们通过sqlalchemy方言赋予我数据库独立性 我发现自己不得不混合我的模块导入来获得我想要的东西。这里是一个简单但典型的导入 from flask import Flask from flask_sqlalchemy i
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import bindparam
from sqlalchemy.sql import text
SQLAlchemy对象随后在我的代码的ORM位中使用,我相信它也会根据需要处理会话。它是这样初始化的
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = appdb
app.config['SQLALCHEMY_BINDS'] = {'meta': foodb, 'data': bardb}
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
eng = db.get_engine(bind='meta')
cxn = eng.connect()
sql = text('select * from foo')
rows = cxn.execute(sql).fetchall()
然后,我使用db
变量访问所有flask\u sqlalchemy内容
直接sqlalchemy的东西在我的核心SQL中使用,看起来像这样
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = appdb
app.config['SQLALCHEMY_BINDS'] = {'meta': foodb, 'data': bardb}
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
eng = db.get_engine(bind='meta')
cxn = eng.connect()
sql = text('select * from foo')
rows = cxn.execute(sql).fetchall()
我现在发现我正在混合代码,例如这样
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = appdb
app.config['SQLALCHEMY_BINDS'] = {'meta': foodb, 'data': bardb}
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
eng = db.get_engine(bind='meta')
cxn = eng.connect()
sql = text('select * from foo')
rows = cxn.execute(sql).fetchall()
在我看来,如果我决定使用flask_sqlalchemy,我不应该单独导入sqlalchemy的东西,它应该在flask_sqlalchemy的某个地方。混合使我对副作用感到紧张
所以我有两个问题
以下对我自己问题的回答概括了我在过去4个月里通过艰苦的学习所学到的一些东西 我是一名数据库程序员,希望使用SQLAlchemy核心SQL与我的数据库而不是ORM对话。下面的代码就是在这种情况下给出的
'''
THE SETUP
'''
maindb = 'dialect+driver://username:password@host:port/main database'
foodb = 'dialect+driver://username:password@host:port/foo database'
bardb = 'dialect+driver://username:password@host:port/bar database'
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = maindb
app.config['SQLALCHEMY_BINDS'] = {'foodb': foodb, 'bardb': bardb}
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
'''
THE CODE USING AN ENGINE
'''
# Using an engine (dbms = database management system).
dbms = db.get_engine(bind='foodb')
cxn = dbms.connect()
sql = db.text('SELECT * FROM foo WHERE foo_id = :id')
parms = {'id': 4}
rows = cxn.execute(sql, parms)
# Get column names, works for all the examples
print(rows.keys())
# Loop through rows and print the column value
for row in rows:
print(row[1]) # Access by position
print(row['foo_name']) # Access by column name
cxn.close
# Providing a list to an IN clause (bindparam with expanding=True)
sql = db.text('select * from foo where foo_id in :ids and foo_name like :nm')
parms = {'ids':[3,4,5], 'nm':'C%'}
for key in parms.keys(): # Apply bindparam to special cases like IN lists
if type(parms[key]) == type([]): # Parameter value is a list
sql = sql.bindparams(db.bindparam(key, expanding = True))
rows = cxn.execute(sql, parms)
print([row['foo_name'] for row in rows])
# Do a database transaction with an engine
txn = cxn.begin()
try:
sql = db.text('update foo set foo_name = :nm where foo_id = :id')
parms = {'id': 4, 'nm':'mr foo bar'}
cxn.execute(sql, parms)
txn.commit()
except:
txn.rollback()
raise
finally:
if cxn != None:
cxn.close()
'''
THE CODE USING A SESSION
'''
# Using a session.
dbms = db.get_engine(bind='foodb')
ssn = db.session(bind=dbms)
sql = db.text('SELECT * FROM foo WHERE foo_id = :id')
parms = {'id': 4}
rows = ssn.execute(sql, parms)
print([row['foo_name'] for row in rows])
# Do a database transaction with a session
breakpoint()
try:
sql = db.text('update foo set foo_name = :nm where foo_id = :id')
parms = {'id': 4, 'nm':'ms bar foo'}
ssn.execute(sql, parms)
ssn.commit()
except:
ssn.rollback()
raise
finally:
if ssn != None:
ssn.close()
通常的SQLAlchemy构造可以通过
db
访问,例如db.text
。db.text是一种数据类型,而不是上面准备执行SQL语句的函数。您确定不是偶然键入db.text
?这两种方法都可以从db
对象中获得。你是一个耐心的天才,非常有效。我已经为其他谨慎的旅行者回答了下面我自己的问题。我还加入了一些其他东西来增加价值:-(0)绑定(1)获取列名(2)在子句中处理(3)引擎和会话(4)事务。