简体   繁体   English

将mysql与pythonanywhere一起使用时的错误4

[英]Error 4 when using mysql with pythonanywhere

So I've continued my python game as from my previous question 所以我从上一个问题开始继续我的python游戏

Socket issue when using threads 使用线程时的套接字问题

and I've come into another issue, this time with MySQL, which is alongside my hosting server on Pythonanywhere.com. 我这次遇到的另一个问题是MySQL,它与我在Pythonanywhere.com上的托管服务器并存。 The error is as follows: 错误如下:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/mysql/connector/network.py", line 191, in recv_plain
    chunk = self.sock.recv(1)
InterruptedError: [Errno 4] Interrupted system call

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/elvishknight1/mysite/flask_app.py", line 81, in intro
    c.execute("SELECT * FROM players WHERE name=%s", (ID,))
  File "/usr/local/lib/python3.4/dist-packages/mysql/connector/cursor.py", line 515, in execute
    self._handle_result(self._connection.cmd_query(stmt))
  File "/usr/local/lib/python3.4/dist-packages/mysql/connector/connection.py", line 684, in cmd_query
    result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
  File "/usr/local/lib/python3.4/dist-packages/mysql/connector/connection.py", line 476, in _send_cmd
    return self._socket.recv()
  File "/usr/local/lib/python3.4/dist-packages/mysql/connector/network.py", line 212, in recv_plain
    errno=2055, values=(self.get_address(), _strioerror(err)))
mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at 'mysql.server:3306', system error: 4 Interrupted system call
2014-12-18 16:27:13,712 :Exception on /chat/ [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/mysql/connector/network.py", line 189, in recv_plain
    packet = self.sock.recv(1)
InterruptedError: [Errno 4] Interrupted system call

duplicates of the above cover the error log as more get requests are made by the server 上面的重复内容覆盖了错误日志,因为服务器发出了更多的获取请求

this is the main app code(apologies if it isn't the most pythonic) 这是主要的应用程序代码(如果不是大多数pythonic,则表示歉意)

from flask import Flask, render_template, request, jsonify
import mysql.connector
from grid import Grid
from game import Game
import random
from monster import Monster
from descriptions import Descriptions
from calculator import Calculator


app = Flask(__name__)
sql = mysql.connector.connect(user="elvishknight1", password="351797asd", host="mysql.server", database="elvishknight1$Overseer", buffered=True)
c = sql.cursor()
game=Game()
grid=Grid()
monsters = []
x=0
y=0
descriptions=Descriptions()
calculator = Calculator()


@app.route('/')
def index():
    return render_template("intro.html",)

@app.route('/mod/351797Aa')
def moderator():
    return render_template("moderate.html",)

@app.route('/mod/')
def worldMaker():
    grid.makeGrid()
    for x in range(4000):
        dice = random.choice(list(descriptions.monsters.keys()))
        mons = descriptions.monsters[dice]
        monsters.append(Monster(dice, mons[0], mons[1], mons[2], mons[3], mons[4],
        mons[5], mons[6], mons[7],mons[8], random.choice(list(range(200))),
        random.choice(list(range(200)))))

    c.execute("UPDATE players SET status='alive'")
    game.gameStatus="started"
    sql.commit()
    return jsonify(result="ok")
@app.route('/player/')
def playerCount():
    return jsonify(result=game.players)

@app.route('/finish/')
def clear():
    game.gameStatus="working on it"
    c.execute("delete from players")
    grid.clearGrid()
    sql.commit()
    return jsonify(result="cleared")

@app.route('/chat/', methods=["GET"])
def chat():
    chatter=[]
    message = request.args.get('value')
    user = request.args.get('user')
    if(message[0:2]=="::"):
        c.execute("INSERT INTO chatPending(user,message) VALUES(%s,%s)",
        (user,message[2:]))
    else:
        del chatter[:]
        c.execute("SELECT * from chatPending")
        row = c.fetchall()
        for r in row:
            if row is not None:
                chatter.append("<p>" + r[0] + ":: " + r[1] + "</p>")
    sql.commit()
    return jsonify(result=chatter)


@app.route('/load/', methods=["GET"])
def intro():
    status=None
    answer = request.args.get('value')
    ID = request.args.get('ID')
    c.execute("SELECT * FROM players WHERE name=%s", (ID,))
    row = c.fetchone()
    if row is not None:
        status = row[3]
    if(game.gameStatus=="started" or game.players>=200):
        status="access denied"
    if(status == None):
        c.execute("INSERT INTO players (name, status) VALUES('" + answer + "', 'entering name')")
        c.execute("SELECT * FROM players WHERE name=%s",(ID,))
        row = c.fetchone()
        if row is not None:
            status = row[3]
    if(status == 'entering name'):
        data = "<p>What is in your past: choose one: <ul> <li> Chosen </li> <li> Magician </li> <li> Poet </li></ul></p>"
        c.execute("UPDATE players SET status='entering past' WHERE name=%s",(ID,))
        c.execute("SELECT * FROM players WHERE name=%s",(ID,))
        row = c.fetchone()
        if row is not None:
            status = row[3]
    elif(status == 'entering past'):
        data = "<p>What is your class. Choose one: <ul> <li> Warrior </li> <li> Mage </li> <li> Rougue </li> <li> Bard </li></ul></p>"
        c.execute("UPDATE players SET status='entering class' WHERE name=%s", (ID,))
        c.execute("UPDATE players SET past=%s WHERE name=%s",(answer.capitalize(), ID))
        c.execute("SELECT * FROM players WHERE name=%s",(ID,))
        row = c.fetchone()
        if row is not None:
            status = row[3]
    elif(status == 'entering class'):
        data = "<p>What is your secret code?</p>"
        c.execute("UPDATE players SET status='entering code' WHERE name=%s", (ID,))
        c.execute("UPDATE players SET class=%s WHERE name=%s",(answer.capitalize(), ID))
        c.execute("SELECT * FROM players WHERE name=%s",(ID,))
        row = c.fetchone()
        if row is not None:
            status = row[3]
    elif(status == 'entering code'):
        data = "<p>OK all set. Waiting on the moderator!</p>"
        c.execute("UPDATE players SET status='waiting' WHERE name=%s", (ID,))
        c.execute("UPDATE players SET code=%s WHERE name=%s",(answer.capitalize(), ID))
        c.execute("SELECT * FROM players WHERE name=%s",(ID,))
        game.players+=1
        row = c.fetchone()
        if row is not None:
            status = row[3]
            past = row[1]
            Class = row[2]
        stats = calculator.calculateStats(past)
        attacks = []
        attackString=""
        equipmentString=""
        equipment = descriptions.classes[Class.capitalize()]
        for a in list(equipment["lHand"][1]["moves"].keys()):
            attacks.append(a)
        for b in list(equipment["rHand"][1]["moves"].keys()):
            attacks.append(b)
        for att in attacks:
            attackString=attackString + att + ","
        for d in equipment:
                equipmentString = equipmentString + d[0] + ","

        c.execute("UPDATE players SET hp=%s,attack=%s,defense=%s,speed=%s, attacks=%s,"
        + "level=1, experience=0, nextLevel=50, energy=%s,inventory=%s, lHand=%s,rHand=%s,head=%s,hands=%s,chest=%s,legs=%s where name=%s",(stats[0],
        stats[1],stats[2],stats[3],attackString,stats[4],equipmentString,
        equipment["lHand"][0],equipment["rHand"][0],equipment["Head"][0],
        equipment["Hands"][0],equipment["Chest"][0],equipment["Legs"][0],ID))

    elif(status == 'waiting'):
        data = "<p>Still waiting, please be patient.</p>"
    elif(status=="access denied"):
        data = "<p>Sorry. The player queue is full.</p>"
    else:
        data="error"
    sql.commit()
    return jsonify(result=data)

@app.route('/check/')
def checker():
    status=None
    ID = request.args.get('user')
    c.execute("SELECT * FROM players WHERE name=%s", (ID,))
    row = c.fetchone()
    if row is not None:
        status = row[3]
    if(status=="alive"):
        data="<p>Ready! Press >> to begin.</p>"
        head="ok"
    else:
        data=""
        head="not"
    return jsonify(result=data, header=head)

@app.route('/move/')
def move():
    y=0
    x=0
    data=""
    answer = request.args.get('value')
    ID = request.args.get('ID')
    c.execute("SELECT * FROM players WHERE name=%s", (ID,))
    row = c.fetchone()
    if row is not None:
        status = row[3]
        x = row[5]
        y = row[6]
        HP = row[7]
        attack = row[8]
        defense = row[9]
        speed = row[10]
        level = row[13]
        energy = row[17]
        Class = row[2]
        past = row[1]
        attacks = row[11]
        exp = row[14]
        nextLevel = row[15]
    if(answer=="start"):
        c.execute("UPDATE players SET X=%s, y=%s WHERE name=%s",(random.choice(list(range(200))),random.choice(list(range(200))), ID))
        data = "You are on a {} tile <br> {} <br>".format(grid.getLandType(x,y), grid.getDesc(x,y))
    if(status!="dead"):
        if(answer=='profile'):
            data = "You're name is {} <br> You are a {} <br> {} <br> your class is: {} <br> your stats are: <br> Level:{} HP:{} <br> Attack:{} <br> Defense:{} <br> Speed:{} <br> Energy:{}".format(ID,past,descriptions.player_backstory[past.lower()],Class,level,HP,attack,defense,speed,energy)
        elif(answer=="North" or answer=="N" and status!="fighting"):
            if(y>0):
                c.execute("UPDATE players SET y=%s WHERE name=%s", (y-1,ID))
            data = "You are on a {} tile <br> {} <br>".format(grid.getLandType(x,y), grid.getDesc(x,y))
        elif(answer=="East" or answer=="E" and status!="fighting"):
            if(x<199):
                c.execute("UPDATE players SET X=%s WHERE name=%s", (x+1,ID))
                c.execute("SELECT * FROM players WHERE name=%s", (ID,))
                row = c.fetchone()
                if row is not None:
                    x = row[5]
            data = "You are on a {} tile <br> {} <br>".format(grid.getLandType(x,y), grid.getDesc(x,y))
        elif(answer=="South" or answer=="S" and status!="fighting"):
            if(y<199):
                c.execute("UPDATE players SET y=%s WHERE name=%s", (y+1,ID))
                c.execute("SELECT * FROM players WHERE name=%s", (ID,))
                row = c.fetchone()
                if row is not None:
                    y = row[6]
            data = "You are on a {} tile <br> {} <br>".format(grid.getLandType(x,y), grid.getDesc(x,y))
        elif(answer=="West" or answer=="W" and status!="fighting"):
            if(x>0):
                c.execute("UPDATE players SET X=%s WHERE name=%s", (x-1,ID))
                c.execute("SELECT * FROM players WHERE name=%s", (ID,))
                row = c.fetchone()
                if row is not None:
                    x = row[5]
            data = "You are on a {} tile <br> {} <br>".format(grid.getLandType(x,y), grid.getDesc(x,y))
        elif(answer=="Attack"):
            for monster in monsters:
                if(x==monster.X and y==monster.Y):
                    data = data + "The {} wakes up, the battle begins".format(monster.name)
                    c.execute("UPDATE players SET status='fighting' WHERE name=%s",(ID,))
                    monsterImFighting = monster
        elif(answer == "Moves" and status=="fighting"):
            c.execute("SELECT * FROM players WHERE name=%s", (ID,))
            row = c.fetchone()
            if row is not None:
                attacks=row[11]
            listOfAttacks=attacks.split(",")
            for y in listOfAttacks:
                data = data + y.capitalize() + "<br>"
        elif(status=="fighting"):
            for m in monsterImFighting.attacks.keys():
                monsterName = m
                for a in attacks.split(","):
                    if(a == answer):
                        damage = calculator.calculateDamage(attack,monsterImFighting.defense,
                        descriptions.classes[Class.capitalize()][1]["moves"][answer],
                        "normal","thunder")
                        data = data + "you deal {} damage to {}".format(damage,m)
                        monsterImFighting.hitpoints-=damage
                        if(monsterImFighting.hitpoints <=0):
                            data = data + "<br> You killed the {}. You gain {} exp.".format(monsterName,monsterImFighting.drops[0])
                            c.execute("UPDATE players SET experience=%s WHERE name=%s",(exp + monsterImFighting.drops[0],ID))
                            c.excecute("SELECT * FROM players WHERE name=%s",(ID,))
                            row = c.fetchone()
                            if row is not None:
                                exp = row[14]
                                c.excecute("UPDATE players SET status='alive' WHERE name=%s",(ID,))
                            if(exp >= nextLevel):
                                data = data + "You've leveled up!!"
                                c.execute("UPDATE players SET level=%s, attack=%s, defense=%s, speed=%s hp=%s WHERE name=%s",(level + 1,
                                attack + random.choice(list(range(3))),defense + random.choice(list(range(3))),
                                speed + random.choice(list(range(3))), HP +random.choice(list(range(20))),ID))

                        else:
                            shuf = random.choice(list(monsterImFighting.attacks.keys()))
                            damageReturn = calculator.calculateReturnDamage(monsterImFighting.attack, defense, monsterImFighting.attacks[shuf])
                            c.execute("UPDATE players SET hp=%s WHERE name=%s",(HP - damageReturn,ID))
                            data=data + "{} deals {} damage to you".format(monsterName,damageReturn)
                            if(HP<=0):
                                data= data + "You have perished at the hands of a {}".format(monsterName)
                                c.execute("UPDATE players SET status='dead' WHERE name=%s",(HP - damageReturn,ID))

        else:
             data = "You are on a {} tile <br> {} <br>".format(grid.getLandType(x,y), grid.getDesc(x,y))
    else:
        data = "Sorry, but you are dead. Dead people don't move"
    sql.commit()
    return jsonify(result=data, header=status)


@app.route('/event/')
def eventManager():
    data = ""

    ID=request.args.get("ID")
    c.execute("SELECT * FROM players WHERE name=%s", (ID,))
    row = c.fetchone()
    if row is not None:
        x = row[5]
    c.execute("SELECT * FROM players WHERE name=%s", (ID,))
    row = c.fetchone()
    if row is not None:
        y = row[6]
    for monster in monsters:
        if(monster.X == x and monster.Y == y):
            data = "A {} is sleeping nearby!".format(monster.name)
    return jsonify(result=data, header=len(monsters))

I've looked on the web for solutions, and they all mention it has something to do with how many connections you are making to the server at once(at least that's what I'm getting from it) but the solutions seem...inconclusive, particularly on how to deal with this when hosting your app on pythonanywhere. 我在网上寻找解决方案,他们都提到它与您一次与服务器建立多少连接有关(至少这是我从中获得的连接),但是解决方案似乎...尚无定论,尤其是在pythonanywhere上托管应用程序时该如何处理。

Any help would be much appreciated! 任何帮助将非常感激!

PythonAnywhere dev here. 这里的PythonAnywhere开发人员。 I really recommend you use MySQL via SQLalchemy rather than directly -- it's a library that sits between your code and the mysql.connector stuff, and it should insulate you from all of the connection management stuff. 我真的建议您通过SQLalchemy而不是直接使用MySQL-它是一个位于代码和mysql.connector之间的库,它应该使您与所有连接管理无关。 That applies on PythonAnywhere or any other hosting platform. 这适用于PythonAnywhere或任何其他托管平台。

The Flask tutorial has some good hints on using SQLAlchemy. Flask教程对使用SQLAlchemy有一些很好的提示。

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

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