Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在react app调用的flask api中使用Sqlite和sqlalchemy的线程和递归问题_Python_Reactjs_Sqlite_Flask_Sqlalchemy - Fatal编程技术网

Python 在react app调用的flask api中使用Sqlite和sqlalchemy的线程和递归问题

Python 在react app调用的flask api中使用Sqlite和sqlalchemy的线程和递归问题,python,reactjs,sqlite,flask,sqlalchemy,Python,Reactjs,Sqlite,Flask,Sqlalchemy,我正在开发一个web应用程序,使用Flask进行API和数据访问,并与MaterialUI进行交互。一般来说,我已经成功地在UI中使用了React组件,使用FlaskAPI从Sqlite获取数据。Flask应用程序设置为将未知请求代理到Flask API 我无法创建代码沙盒,因为我无法为Flask或SQLAlchemy添加依赖项 应用程序几乎完成了;我能够使用Flask和API从几个不同的表中获取数据。然后,我添加了一个数据过滤器选择组件和一个对API的调用,以从设置表中获取最后一个过滤器选择,

我正在开发一个web应用程序,使用Flask进行API和数据访问,并与MaterialUI进行交互。一般来说,我已经成功地在UI中使用了React组件,使用FlaskAPI从Sqlite获取数据。Flask应用程序设置为将未知请求代理到Flask API

我无法创建代码沙盒,因为我无法为Flask或SQLAlchemy添加依赖项

应用程序几乎完成了;我能够使用Flask和API从几个不同的表中获取数据。然后,我添加了一个数据过滤器选择组件和一个对API的调用,以从设置表中获取最后一个过滤器选择,该简单调用以两种方式中断:

  • 正在重复调用对getFilter的API调用。我不知道该怎么做才能阻止它。加载值是一个调用onChange的更改,onChange重新加载导致更改的设置。我确信这是我如何实现它的一个bug,但我不知道如何修复它。事件处理程序位于FilterSelector的祖父母组件app.js中,发生更改的地方。该错误一直重复,直到我收到一个错误,Python无法创建更多线程,然后Flask应用程序被挂起,必须通过关闭我正在运行它的PowerShell窗口来关闭该应用程序,在此之后,React应用程序提供一个http 500,它无法代理Flask应用程序

  • 对API的调用来自不同的线程-每一次调用都会创建一个新线程,Sqlite抱怨在一个线程中创建的对象在另一个线程中不可用:

  • 我不知道递归是由于线程错误还是线程错误是由于递归。我不希望Python或sqlalchemy为这些调用创建多个线程

    我希望我能为此创建一个codeplaypen,但我不能,所以代码如下:

    反应代码:

    package.json末尾的这一行允许应用程序代理对API作出反应:

    "proxy": "http://localhost:5000"
    
    app.js

    import React, { useState, useEffect } from 'react';
    import Users from './Components/Users/Users';
    
    export default function UserManager() {
    
      const [Filter, setFilter] = useState('all');
      useEffect(() => {
        fetch('/api/getFilter').then(res => res.text()).then(data => {
          console.log(new Date() + "Filter useEffect data = " + data);
          setFilter(data);
          console.log(new Date() + "Filter useEffect set to: " + Filter)
          });
        }
      )  
      const filterChanged = (event, selectedFilter) => {
        alert('app.js filter changed! Filter=' + Filter + ' and selectedFilter=' + selectedFilter);
        setFilter(selectedFilter);
      };
      
      return (  
              <div>
                <Users 
                filterChanged={filterChanged.bind(this)} 
                filter={ Filter } 
              />
              </div>
       )
    }
    
    我确保没有任何其他实例接触数据库文件;关闭所有VSCode窗口、所有资源管理器窗口,甚至重新启动,然后重新启动React和Flask应用程序。非常奇怪的是,这段代码只会导致问题,而我的其他数据库调用代码都不会


    我知道在没有codesandbox的情况下评估这是一个复杂的场景,但我肯定会非常感谢任何帮助。我知道欣赏不如啤酒好,但这是我现在所得到的一切。

    模块范围内的session=DBSession()是线程问题的根源,因为session实例不是线程安全的。在适当的范围内创建会话,或者如果使用线程作为例如请求范围,则使用。简要回顾:引擎是连接池的便捷外壳,它是线程安全的。另一方面,连接不是,所以不要在线程之间共享这些连接。会话也不是线程安全的,因此没有共享。所以在模块范围和会话工厂中创建引擎,而不是会话。就是这样。它解决了递归问题和线程问题。非常感谢。
    import React, { useState, useEffect } from 'react';
    import Users from './Components/Users/Users';
    
    export default function UserManager() {
    
      const [Filter, setFilter] = useState('all');
      useEffect(() => {
        fetch('/api/getFilter').then(res => res.text()).then(data => {
          console.log(new Date() + "Filter useEffect data = " + data);
          setFilter(data);
          console.log(new Date() + "Filter useEffect set to: " + Filter)
          });
        }
      )  
      const filterChanged = (event, selectedFilter) => {
        alert('app.js filter changed! Filter=' + Filter + ' and selectedFilter=' + selectedFilter);
        setFilter(selectedFilter);
      };
      
      return (  
              <div>
                <Users 
                filterChanged={filterChanged.bind(this)} 
                filter={ Filter } 
              />
              </div>
       )
    }
    
    import React, { Component } from 'react'
    import FilterSelector from './FilterSelector'
    
    export class Users extends Component {
        
        
        render() {
            const filter = this.props.filter;
            console.log(this.props.filter)
            console.log("Users render - " + this.props.filter);
            return (<FilterSelector filter={filter} filterChanged={this.props.filterChanged.bind(this)}/>)
        }
    }
    
    export default Users
    
    import React from 'react';
    import Radio from '@material-ui/core/Radio';
    import RadioGroup from '@material-ui/core/RadioGroup';
    import FormControlLabel from '@material-ui/core/FormControlLabel';
    import FormControl from '@material-ui/core/FormControl';
    import FormLabel from '@material-ui/core/FormLabel';
    
    export default function FilterSelector(props) {
    
      return (
        <FormControl component="fieldset">
          <FormLabel component="legend">Filter</FormLabel>
          <RadioGroup aria-label="filters" name="filter1" value={ props.filter } onChange={ props.filterChanged }>
            <FormControlLabel value="favorites" control={<Radio />} label="Favorites" />
            <FormControlLabel value="included" control={<Radio />} label="Included" />
            <FormControlLabel value="all" control={<Radio />} label="All" />
          </RadioGroup>
        </FormControl>
      );
    }
    
    import time
    from flask import Flask
    import userdata
    import json
    import datetime
    
    import subprocess
    app = Flask(__name__)
    
    
    @app.route('/api/getFilter')
    #sample: http://localhost:5000/api/getFilter
    def getFilter():
        print ("In getFilter")
        #return "favorites"
        filter = userdata.getSetting('filter')
    
        print ("{0}In api getFilter().  Filterdata from db is: {1}".format(datetime.datetime.now(), filter))
        
        if filter is None:
            #userdata.updateSetting('channelfilter', 'all')
            filter = 'favorites' 
        print ("In getfilter2")
        return filter
    
    """
    @app.route('/api/saveFilter/<filterValue>')
    #sample: http://localhost:5000/api/saveFilter/favorites
    def saveFilter(filterValue):
        userdata.updateSetting('filter', filterValue)
        return filterValue
    """
    #Below route is for development testing only, remove for production.
    @app.route('/api/getUsers')
    #sample: http://localhost:5000/api/getUsers
    def getUsersFromDB():
        return json.loads(userdata.GetUsers())
    
    @app.route('/api/getUsers/<filter>')
    #sample: http://localhost:5000/api/getUsers/favorites
    def getUsersFromDBFiltered(filter):
        print("In getUsersFiltered. filter = {0}".format(filter))
        return json.loads(userdata.GetUsers())
    
    if __name__ == '__main__':
            app.run(debug=True, host='0.0.0.0')
    
    from sqlalchemy import Column, ForeignKeyConstraint, UniqueConstraint
    from sqlalchemy import PrimaryKeyConstraint, Integer, String, Boolean, DateTime, func
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import relationship
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import text
    import json
    import os
    
    Base = declarative_base()
    Engine = create_engine('sqlite:///data/users.db')
    Base.metadata.bind = Engine
    DBSession = sessionmaker(bind=Engine)
    session = DBSession()
    
    class Settings(Base):
        __tablename__ = "settings"
        settingname = Column(String(80), primary_key=True)
        settingvalue = Column(String(80), nullable=False)
    
    
    def ResultSetQueryToJson(resultSet):
        print ('Not Yet Implemented.')
        return resultSet
            
    def ResultSetDeclarativeToJson(resultSet):
        jsontext = "{{\n\t\"{0}\": [".format(resultSet[0].__table__.name)
    
        for datarow in resultSet:
            rowsdata = ""
            columncount = len(datarow.__table__.columns)
            if jsontext.endswith("}"):
                jsontext += ","
            jsontext += "{\n"
            for c in datarow.__table__.columns:
                columncount -= 1
                rowsdata = rowsdata + "\n\t\t\"{0}\": \"{1}\"".format(c.key, getattr(datarow, c.key))
                if columncount > 0:
                    rowsdata += ","
            jsontext += rowsdata
            jsontext += "\n\t}"
        return jsontext + "]\n}"
    
    
    def getSettings():
        print("Start getSettings())")
        return session.query(Settings).all()
    
    def getSetting(sname):
        print("Starting userdata.getSetting() for {0}.".format(sname))
        result = session.query(Settings).filter(Settings.settingname == sname).one_or_none()
        print ("in getSetting.  Query Result = {0}".format(result))
        if result is not None:
            svalue = result.settingvalue
            print('Got setting {0}: {1}'.format(sname, svalue))
            return svalue
        return None
    
    
    """
    def updateSetting(sname, svalue):
        setting = Settings()
        setting.settingname = sname
        setting.settingvalue = svalue
        session.merge(setting)
        session.commit()
    
    """
    
    
    class Apps(Base):
        __tablename__ = 'apps'
        appid = Column(String(24), primary_key=True)
        name = Column(String(250), nullable=False)
        vendor = Column(String(80), nullable=True)
        version = Column(String(50), nullable=False)
        isDeleted = Column(Boolean, nullable=False)
    
    class Users(Base):
        __tablename__ = 'users'
        userid = Column(String(80), primary_key=True)
        lastname = Column(String(40), nullable=False)
        firstname = Column(String(40), nullable=False)
        emailaddress = Column(String(80), nullable=False)
    
    def ReflectTableColumns(DbEngine, meta, targetTable):
        tableschema = Table(targetTable, meta, autoload=True, autoload_with=DbEngine)
        cols = dict()
        for c in tableschema.columns:
            print("{0}\t|\t{1}".format(c.name, c.type))
            cols[c.name] = c.type
        
        return cols
    
    def GetUsers():
        DBSession = sessionmaker(bind=Engine)
        session = DBSession()
        results = session.query(Users).all()
        ShowTableData(results, 'users')
        return ResultSetDeclarativeToJson(results)