我有一个基于Pylons的Web应用程序,它通过Sqlalchemy(v0.5)连接到Postgres数据库.为了安全起见,而不是遵循简单的Web应用程序的典型模式(如几乎所有教程中所见),我没有使用通用的Postgres用户(例如"webapp"),但要求用户输入他们自己的Postgres用户ID和密码,并使用它来建立连接.这意味着我们可以获得Postgres安全性的全部好处.
更复杂的是,有两个独立的数据库可以连接.虽然它们目前位于同一个Postgres集群中,但它们需要能够在以后转移到单独的主机.
我们正在使用sqlalchemy的声明包,但我看不出这与此有关.
sqlalchemy的大多数示例都显示了一些简单的方法,例如在应用程序启动时使用通用Web用户和密码设置元数据,通过Web应用程序使用.这通常使用Metadata.bind = create_engine()完成,有时甚至在数据库模型文件中的模块级别完成.
我的问题是,在用户登录之前,我们如何推迟建立连接,然后(当然)为每个后续请求重新使用这些连接,或者使用相同的凭证重新建立连接.
我们有这个工作 - 我们认为 - 但我不仅不确定它的安全性,我还认为它看起来非常重.
里面__call__的BaseController的方法,我们从Web上获得会话每个数据库的用户名和密码,调用SQLAlchemy的create_engine()一次,然后调用它调用Session.bind_mapper(常规)多次,一次为每个表可在每个被引用这些连接,即使任何给定的请求通常只引用一个或两个表.它看起来像这样:
# in lib/base.py on the BaseController class
def __call__(self, environ, start_response):
# note: web session contains {'username': XXX, 'password': YYY}
url1 = 'postgres://%(username)s:%(password)s@server1/finance' % session
url2 = 'postgres://%(username)s:%(password)s@server2/staff' % session
finance = create_engine(url1)
staff = create_engine(url2)
db_configure(staff, finance) # see below
... etc
# in another file
Session = scoped_session(sessionmaker())
def db_configure(staff, finance):
s = Session()
from db.finance import …Run Code Online (Sandbox Code Playgroud) 我有一个在 WSGI 下提供的 Flask 应用程序,其中数据库 URI 会随时间变化。URI 每两小时切换到另一个数据库。我利用这段时间填充一个数据库,而另一个数据库则为应用程序提供数据。
我很难弄清楚如何最好地配置会话,以便在切换发生时,客户端将在下一个请求中获得正确的(不同的)数据库。根据我的测试,如果我在顶层初始化数据库,当切换发生时,客户端仍然指向旧数据库。
我想过在页面(索引等)内部设置会话,但是太痛苦了,然后我担心打开和关闭太多的数据库连接并让它们闲置。我想我可以通过在启动时初始化两个会话来使其工作,然后只需选择在每个页面内的切换时使用哪个会话。这似乎效率低下,我相信有更好的方法。
帮助?!
~~~~~~~~~
这是我目前正在做的事情的一般想法,但无法更改请求之间的 URI。顶级代码只运行一次,或者每隔一段时间运行一次。
if now.hour % 2:
db_name = 'db1'
else:
db_name = 'db2'
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://foo:poo@localhost:3306/%s" % db_name
def init_db(uri, **kwargs):
engine = create_engine(uri, **kwargs)
Base.metadata.create_all(bind=engine)
global db_session
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base.query = db_session.query_property()
init_db(app.config['SQLALCHEMY_DATABASE_URI'], pool_recycle=3600)
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
@app.route('/')
def index():
...etc...
Run Code Online (Sandbox Code Playgroud)
工作示例 - 美丽。
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://foo:poo@localhost:3306/%s"
class SessionManager(object):
def __init__(self, base_uri=None, **kwargs):
self.session = None
self.base_uri …Run Code Online (Sandbox Code Playgroud) 我有一个主数据库,其中存储了每个客户端自己的数据库连接.所以每个客户端都使用2 db:main和它自己的db,必须为每个http调用决定连接.我怎样才能使用flask-sqlalchemy扩展,或者纯粹是sqlalchemy?