这是我做的:
from flask import Flask
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
dbhost = 'localhost'
dbuser = 'user'
dbpass = 'password'
dbname = 'db'
DBUri = 'mysql://%s:%s@%s/%s?charset=utf8'%(dbuser,dbpass,dbhost,dbname)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = (DBUri)
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
# an Engine, which the Session will use for connection
# resources
engine = create_engine(DBUri)
# create a configured "Session" class
Session = sessionmaker(bind=engine)
# create a Session
DBsession = Session()
和
@sched.cron_schedule(second='*/5')
def some_decorated_task():
date_now = datetime.datetime.now().date()
for item in DBsession.query(user_groups_n_hosts).filter(user_groups_n_hosts.end_time < str(date_now)):
print item.id, item.server_users.native_linux_user
有一个表 user_groups_n_hosts 上面的代码是一个每30秒运行一次的函数。
我的问题是,如果 user_groups_n_hosts 有10条记录,那么当我启动Flask应用程序时,无论在表格中插入多少条记录,上述代码都将继续打印10条记录<来自外部的strong> user_groups_n_hosts 。换句话说,我认为我的函数有一些表的实例,它只在应用程序初始化时初始化。 我知道我做的事情很愚蠢。请有人指出来。
取代DBsession.query(user_groups_n_hosts).filter(user_groups_n_hosts.end_time < str(date_now)):
我试过user_groups_n_hosts.query.filter(user_groups_n_hosts.end_time < str(date_now)):
但结果是一样的。
答案 0 :(得分:1)
您的过滤器user_groups_n_hosts.end_time&lt; str(date_now)将日期与字符串进行比较。
此外,您应该将会话视为按请求进行操作,而不是整个应用中的持久实体。
考虑到这一点,请尝试更改
@sched.cron_schedule(second='*/5')
def some_decorated_task():
date_now = datetime.datetime.now().date()
for item in DBsession.query(user_groups_n_hosts).filter(user_groups_n_hosts.end_time < str(date_now)):
print item.id, item.server_users.native_linux_user
到
@sched.cron_schedule(second='*/5')
def some_decorated_task():
date_now = datetime.datetime.now().date()
sess = Session()
for item in sess.query(user_groups_n_hosts).filter(user_groups_n_hosts.end_time < str(date_now)):
print item.id, item.server_users.native_linux_user
sess.close()
答案 1 :(得分:1)
您每次都需要建立一个新的交易。
您可以在每次运行时创建一个全新的会话对象,重新使用会话,但在查询后确保commit()
,rollback()
或close()
。
这种影响是由MySQL的一些默认策略引起的。
如果您使用InnoDB作为MySQL的默认存储引擎,则它使用REPEATABLE READ
作为其隔离级别。这是默认值,因为在大多数情况下,避免事务内部Non-repeatable Reads是有意义的。
因此,如果您没有结束交易,您每次都会从数据库中获得相同的结果。
会话无论何时用于与数据库通信,都会在开始通信时立即开始数据库事务。假设autocommit标志保持其建议的默认值False,则此事务将继续进行,直到会话回滚,提交或关闭。如果在先前的交易结束之后再次使用会话,则会话将开始新的交易;由此得出,会话能够在许多交易中具有生命周期,尽管一次只能有一个交易。我们将这两个概念称为交易范围和会话范围。
另一个选项不推荐,正在使用autocommit=True
创建会话,该会话将在每个查询语句之后自动提交事务。