Python 同时使用sqlalchemy和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

我已经在一个烧瓶应用程序,是数据库密集型约4个月的工作。我对python、flask和sqlalchemy非常陌生,但对web和数据库编程非常熟悉

我主要使用核心SQL作为硬数据库,但也使用了ORM。我在核心SQL中使用的主要方法是text()和bindparam()函数,它们通过sqlalchemy方言赋予我数据库独立性

我发现自己不得不混合我的模块导入来获得我想要的东西。这里是一个简单但典型的导入

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的某个地方。混合使我对副作用感到紧张

所以我有两个问题

  • 这样混合安全吗
  • 我可以得到text()和 bindparam()和烧瓶中的其他sqlalchemy材料?如果 那怎么办

  • 以下对我自己问题的回答概括了我在过去4个月里通过艰苦的学习所学到的一些东西

    我是一名数据库程序员,希望使用SQLAlchemy核心SQL与我的数据库而不是ORM对话。下面的代码就是在这种情况下给出的

  • 绑定并使用多个数据库
  • 获取列名
  • 条款处理
  • 引擎v会话
  • 交易
  • 我希望它能帮助别人

    '''
    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)事务。