如何创建一个永远运行的后台任务-Python FlaskSQLAlchemy

问题描述 投票:0回答:1

我想创建一个永远运行的简单后台任务。我将找到一种方法,与我在Flask中编写的Web应用程序同时启动它。

到目前为止我所拥有的是:

import threading
from app.models import SkillTracker, UserAttributes
from flask_sqlalchemy import SQLAlchemy
from app import db
import time, math

class SkillTimer(threading.Thread, SkillTracker):
    def __init__(self, SkillTracker=SkillTracker):
        threading.Thread.__init__(self)
        self.skillcheck = SkillTracker.query.filter_by(isactive=1).all()
    def run(self):
            # for x in range(1, 1+1):
            #     if x%1 == 0:
            #         print(x)
            # #print(x)
            time.sleep(1)
            self.skillcheck = SkillTracker.query.filter_by(isactive=1).all()

            if self.skillcheck != []:
                print(self.skillcheck)
                for record in self.skillcheck:
                    if record.isactive == 1:
                        if record.timesubmit + record.timetowait <= time.time():
                            user = UserAttributes.query.filter_by(user_id=record.userid).first()
                            if record.targetskill == 'int':
                                record.isactive = 0
                                user.intelligence += 1
                                db.session.commit()
                                print('User {} upgraded {}, level = {} -- {}'.format(user.user_id, record.targetskill,
                                                                                     user.intelligence, time.time()))
                            if record.targetskill == 'end':
                                record.isactive = 0
                                user.endurance += 1
                                db.session.commit()
                                print('User {} upgraded {}, level = {} -- {}'.format(user.user_id, record.targetskill,
                                                                                     user.endurance, time.time()))
                            if record.targetskill == 'str':
                                record.isactive = 0
                                user.strength += 1
                                db.session.commit()
                                print('User {} upgraded {}, level = {} -- {}'.format(user.user_id, record.targetskill,
                                                                                     user.strength, time.time()))
            else:
                pass
            self.skillcheck = None
            skilltime = SkillTimer()
            skilltime.run()


#while True:
skilltime = SkillTimer()
skilltime.run()
#skilltimer.run()

并且这可以像你期望的那样完美地工作,但是,在运行超过~950次之后我遇到了问题。我得到一个递归错误如下:

Traceback (most recent call last):
  File "D:\Anaconda3\lib\runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "D:\Anaconda3\lib\runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "D:\Anaconda3\feuadal_kingdom\app\Skilltimer.py", line 52, in <module>
    skilltime.run()
  File "D:\Anaconda3\feuadal_kingdom\app\Skilltimer.py", line 47, in run
    skilltime.run()
  File "D:\Anaconda3\feuadal_kingdom\app\Skilltimer.py", line 47, in run
    skilltime.run()
  File "D:\Anaconda3\feuadal_kingdom\app\Skilltimer.py", line 47, in run
    skilltime.run()
  [Previous line repeated 923 more times]
  File "D:\Anaconda3\feuadal_kingdom\app\Skilltimer.py", line 46, in run
    skilltime = SkillTimer()
  File "<string>", line 4, in __init__
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\orm\state.py", line 414, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\util\langhelpers.py", line 60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 187, in reraise
    raise value
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\orm\state.py", line 411, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "D:\Anaconda3\feuadal_kingdom\app\Skilltimer.py", line 10, in __init__
    self.skillcheck = SkillTracker.query.filter_by(isactive=1).all()
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 2638, in all
    return list(self)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 2790, in __iter__
    return self._execute_and_instances(context)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\orm\query.py", line 2813, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 945, in execute
    return meth(self, multiparams, params)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 263, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1046, in _execute_clauseelement
    if not self.schema_for_object.is_default else None)
  File "<string>", line 1, in <lambda>
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 436, in compile
    return self._compiler(dialect, bind=bind, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 442, in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 435, in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 216, in __init__
    self.string = self.process(self.statement, **compile_kwargs)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 242, in process
    return obj._compiler_dispatch(self, **kwargs)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
    return meth(self, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1738, in visit_select
    text, select, inner_columns, froms, byfrom, kwargs)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1822, in _compose_select_body
    t = select._whereclause._compiler_dispatch(self, **kwargs)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
    return meth(self, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1025, in visit_binary
    return self._generate_generic_binary(binary, opstring, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1050, in _generate_generic_binary
    self, eager_grouping=eager_grouping, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
    return meth(self, **kw)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1183, in visit_bindparam
    name = self._truncate_bindparam(bindparam)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1239, in _truncate_bindparam
    bind_name = self._truncated_identifier("bindparam", bind_name)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1250, in _truncated_identifier
    anonname = name.apply_map(self.anon_map)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 4079, in apply_map
    return self % map_
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\util\_collections.py", line 729, in __missing__
    self[key] = val = self.creator(key)
  File "D:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1269, in _process_anon
    return derived + "_" + str(anonymous_counter)
RecursionError: maximum recursion depth exceeded while getting the str of an object

这会杀死这个过程,我不敢通过例外,因为它是有原因的。

我的问题是,有没有一种方法可以调整这个线程类,以便它可以运行无限次?

我觉得这可以通过每次重新启动类线程来解决,但同样,我不完全确定如何创建这种无限循环。

唯一需要注意的是,此时我只是测试所以任何解决方案都应该可以通过键盘中断。

如果您需要进一步明确,请告诉我,数据库模型或烧瓶路径中没有任何错误,除了在达到递归限制后的错误之外,一切都能正常运行。例如。增加递归限制只会延迟错误,而不是解决它。

python multithreading flask sqlalchemy
1个回答
1
投票

我会改变它:

import threading
from app.models import SkillTracker, UserAttributes
from flask_sqlalchemy import SQLAlchemy
from app import db
import time, math

class SkillTimer(threading.Thread, SkillTracker):
    def __init__(self, SkillTracker=SkillTracker):
        threading.Thread.__init__(self)
        self.skillcheck = SkillTracker.query.filter_by(isactive=1).all()
    def run(self):
        while True:
            time.sleep(1)
            self.skillcheck = SkillTracker.query.filter_by(isactive=1).all()

            if self.skillcheck != []:
                print(self.skillcheck)
                for record in self.skillcheck:
                    if record.isactive == 1:
                        if record.timesubmit + record.timetowait <= time.time():
                            user = UserAttributes.query.filter_by(user_id=record.userid).first()
                            if record.targetskill == 'int':
                                record.isactive = 0
                                user.intelligence += 1
                                db.session.commit()
                                print('User {} upgraded {}, level = {} -- {}'.format(user.user_id, record.targetskill,
                                                                                     user.intelligence, time.time()))
                            if record.targetskill == 'end':
                                record.isactive = 0
                                user.endurance += 1
                                db.session.commit()
                                print('User {} upgraded {}, level = {} -- {}'.format(user.user_id, record.targetskill,
                                                                                     user.endurance, time.time()))
                            if record.targetskill == 'str':
                                record.isactive = 0
                                user.strength += 1
                                db.session.commit()
                                print('User {} upgraded {}, level = {} -- {}'.format(user.user_id, record.targetskill,
                                                                                     user.strength, time.time()))
            else:
                pass
            self.skillcheck = None


skilltime = SkillTimer()
skilltime.run()
© www.soinside.com 2019 - 2024. All rights reserved.