简体   繁体   English

Python API 函数以意外顺序调用

[英]Python API functions called in unexpected order

I'm a fullstack developer (mainly php+js) and started to experiment with python.我是一名全栈开发人员(主要是 php+js)并开始尝试使用 python。 My python knowledge is like 5 days old and I'm facing strange problem with order of code execution.我的 python 知识已经有 5 天了,我在代码执行顺序方面遇到了奇怪的问题。 Lets start with the code:让我们从代码开始:

app.py应用程序.py

from flask import Flask, request
from libs.dullapi import Dullapi
from libs.db_manager import DbManager

app = Flask(__name__)
db = DbManager()
dullapi = Dullapi(db)

@app.route('/')
def main():
    return dullapi.hello_world()

@app.route('/begin-interrogation', methods=['POST'])
def newHole():
    return dullapi.newHole(request)

db_manager.py db_manager.py

import sqlite3
class DbManager:
    _conobj: sqlite3.Connection

    def __init__(self) -> None:
        self._conobj = sqlite3.connect('../sol.db', check_same_thread=False)

    def holes(self):
        dbres = self._conobj.execute('SELECT * FROM holes')
        return dbres.fetchall()

    def getConnection(self) -> sqlite3.Connection:
        return self._conobj

    def execParams(self, query: str, params):
        cursor = self._conobj.cursor()
        cursor.execute(query, params)
        self._conobj.commit()

    def end(self) -> None:
        self._conobj.close()

dullapi.py笨拙的.py

from flask import Request
from libs.db_manager import DbManager
import time
import uuid

class Dullapi:
    db: DbManager

    def __init__(self, db: DbManager) -> None:
        self.db = db

    def hello_world(self):
        data = self.db.holes()
        self.db.end()
        return {
            "ewhat": 14,
            'holes': data
        }

    def newHole(self, req: Request):
        newHid = uuid.uuid4()
        self.db.execParams('INSERT INTO holes (hole_id, creator_id, created_at) VALUES (:hid, :cid, :cat)', {
            "hid": str(newHid),
            "cid": req.get_json()['uid'],
            "cat": int(time.time())
        })
        self.db.end()

        return {
            'rid': str(newHid),
            'status': 1
        }

And /begin-interrogation endpoint gives me this error sqlite3.ProgrammingError: Cannot operate on a closed database.并且/begin-interrogation端点给了我这个错误sqlite3.ProgrammingError: Cannot operate on a closed database. with traceback indicating error on line where self.db.execParams is called.回溯指示调用self.db.execParams的行有错误。

This is very simple code - I know, but I did a lot different APIs with "this" idea of database manager class without problem like this - but only in PHP.这是非常简单的代码——我知道,但我用数据库管理器 class 的“这个”想法做了很多不同的 API,没有这样的问题——但仅限于 PHP。

Is Python multithreaded like for each function call or somehow calls functions asynchronously? Python 是多线程的,就像每个 function 调用一样,还是以某种方式异步调用函数?

Like mipadi said, you likely already closed the connection to the database with a different request.就像 mipadi 所说,您可能已经使用不同的请求关闭了与数据库的连接。 What I usually do is to not make a global database connection objcect, but rather initialize a new connection on every request where I need it.我通常做的是不创建全局数据库连接对象,而是在我需要的每个请求上初始化一个新连接。 Then I save the connection object in a global variable.然后我将连接 object 保存在全局变量中。 Flask has the g object for this ( from flask import g ), which is "unique" for every request and can only be used within a request context . Flask 为此具有g object ( from flask import g ),对于每个请求都是“唯一的”,并且只能在请求上下文中使用。

Example function you could use to always get a connection, but reuse open ones:示例 function 您可以用来始终获得连接,但重用打开的连接:

from flask import g

def get_db():
    if not hasattr(g, "db"):
        g.db = DbManager()

    return g.db

In your case it might make sense to incorporate this into your existing DbManager class:)在您的情况下,将其合并到您现有的DbManager class 中可能是有意义的:)

For closing connections after every request you might want to look at this .对于在每次请求后关闭连接,您可能需要查看this

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM