sqlite TypeError:‘fp’不是一个类似文件的对象,或者它不接受字节:‘BaseQuery’对象没有属性‘strie’

tyg4sfes  于 2022-11-14  发布在  SQLite
关注(0)|答案(1)|浏览(162)

我希望我已经添加了找出代码错误所需的所有内容。当我在我的网站上工作时,我不断收到这个错误。根据回溯,我认为这个问题的根源在于simquestion = db.session.query(Tournamentsim.question).order_by(func.random()).limit(1)和/或tts.save(file_location)的views.py。当我使用'hello'而不是simquestion时,它可以工作。这就是为什么当我试图从Tournamentsim那里得到一个问题时,我认为有问题。我一直在研究类似的问题,但似乎找不到答案。我希望我能找到一些帮助。代码如下:
Models.py

class Tournamentsim(db.Model):
    id=db.Column(db.Integer, primary_key=True)
    question=db.Column(db.String(1000))
    answer=db.Column(db.String(500))

Views.py

@views.route('/test-yourself/tournament-simulator')
    @login_required
    def test_yourself_tournament_simulator():
        generated_audio_filename = secrets.token_hex(10) + ".mp3"
    
        simquestion = db.session.query(Tournamentsim.question).order_by(func.random()).limit(1)   
    
        tts = gTTS(simquestion, lang='en')
        
        file_location = os.path.join(
            app.config["AUDIO_FILE_UPLOAD"],
            generated_audio_filename
        )
    
        tts.save(file_location)
    
        return render_template(
            "test-yourself/tournament-simulator.html", 
            title="Hello",
            user=current_user, 
            audio=True, 
            file=generated_audio_filename
        )

以下是回溯:
Traceback (most recent call last) (Part 1)
During handling of the above exception, another exception occurred: (Part 2)

bkhjykvo

bkhjykvo1#

该问题是由于您没有传递请求的字符串,而是传递数据库查询作为一个整体。
要获得随机问题的文本,缺少关键字first()。您可以在这里没有限制,因为只请求了一个元素。但是,将返回一个包含问题文本的元组。因此,确切的查询如下所示。

question_text = db.session.query(Tournamentsim.question)\
        .order_by(func.random())
        .first()[0]

或者,您也可以使用以下表达式。

question_text = Tournamentsim.query\
        .order_by(func.random())\
        .with_entities(Tournamentsim.question)\
        .first()[0]

下面是这个简单示例的完整代码。

from flask import (
    Flask, 
    render_template, 
    send_from_directory
)
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import func
from gtts import gTTS
import os, secrets 

db = SQLAlchemy()
app = Flask(__name__)
app.config.from_mapping(
    SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(app.instance_path, 'sample.db'),
    SQLALCHEMY_TRACK_MODIFICATIONS=False,
    UPLOAD_FOLDER=os.path.join(app.instance_path, 'uploads')
)

for folder in (app.instance_path, app.config['UPLOAD_FOLDER'],):
    try: 
        os.makedirs(folder)
    except OSError: 
        pass

db.init_app(app)

class Tournamentsim(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    question = db.Column(db.String)
    answer = db.Column(db.String)

with app.app_context():
    db.drop_all()
    db.create_all()

    ts = [Tournamentsim(question=f'q-{i}', answer=f'a-{i}') for i in range(20)]
    db.session.add_all(ts)
    db.session.commit()

@app.route('/')
def index():
    filename = secrets.token_hex(10) + '.mp3'
    filepath = os.path.join(
        app.config['UPLOAD_FOLDER'], 
        filename 
    )

    q,*_ = Tournamentsim.query\
        .order_by(func.random())\
        .with_entities(Tournamentsim.question)\
        .first()
    tts = gTTS(q, lang='en')
    tts.save(filepath)

    return render_template('index.html', file=filename)

@app.route('/download/<path:filename>')
def download(filename):
    return send_from_directory(
        app.config['UPLOAD_FOLDER'], 
        filename, 
        mimetype='audio/mpeg', 
        as_attachment=True
    )
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Index</title>
</head>
<body>
    <audio src="{{ url_for('download', filename=file) }}" controls></audio>
</body>
</html>

作为一个提示:
您也可以直接传送音频文件,而无需保存。

from flask import send_file
import io

# ...

@app.route('/question')
def question():
    q,*_ = Tournamentsim.query\
        .order_by(func.random())\
        .with_entities(Tournamentsim.question)\
        .first()
    tts = gTTS(q, lang='en')
    fp = io.BytesIO()
    tts.write_to_fp(fp)
    fp.seek(0)
    return send_file(
        fp, 
        mimetype='audio/mpeg', 
        download_name='question.mp3', 
        as_attachment=True
    )

相关问题