Vyhnout se „MySQL server odešla pryč“ na zřídka používané Python / Flask serveru s SQLAlchemy

hlasů
35

Jak může být baňka / SQLAlchemy nakonfigurován pro vytvoření nového připojení k databázi, pokud jeden není k dispozici?

Mám občas navštívil Python / Flask server, který používá SQLAlchemy. Se dostane na každých pár dní, a již při první návštěvě se často hází „MySQL server odešla pryč“ chybu. Následné zobrazení stránek jsou v pořádku, ale vypadá to neprofesionální, aby byl tento počáteční chyby.

Chtěl bych znát správný způsob, jak řešit tento problém - radu jako „dělat opravdu dlouho out“, což by bylo asi 4 dnů dlouho v tomto případě nezdá správné. Jak mohu otestovat nedostatek připojení databáze av případě potřeby vytvořit?

Položena 24/06/2011 v 18:34
zdroj uživatelem
V jiných jazycích...                            


8 odpovědí

hlasů
38

Měl jsem problémy s dříve, a zjistil, že způsob, jak zvládnout to je tím, že udržuje relace kolem. Potíž je v tom se snaží udržet spojení otevřené pro cesty příliš dlouho. Místo toho použijte nit místní scoped relace tak jako buď v __init__.pyči užitného balíčku, který importujete všude:

from sqlalchemy.orm import scoped_session, sessionmaker
Session = scoped_session( sessionmaker() )

Pak nastavit své motory a metadata jednou. To vám umožní přeskočit konfigurace mechaniku při každém připojení / odpojení. Za to, že si můžete dělat svou práci db takto:

session = Session()
someObject = session.query( someMappedClass ).get( someId )
# use session like normal ...
session.close()

Chcete-li držet starých objektů a nechcete opustit své relace otevřené, pak můžete použít výše uvedený vzorec a znovu staré předměty, jako je tato:

session = Session()
someObject = session.merge( someObject )
# more db stuff
session.close()

Jde o to, že chcete otevřít relaci, dělat svou práci, zavřete relaci. Tím se zabrání prodlevám velmi dobře. Existuje spousta možností pro .merge a .add, které vám umožní buď zahrnovat změny, které jste provedli na samostatných objektů nebo k načtení nových dat z db. Tyto dokumenty jsou velmi upovídaný, ale jakmile víte, co hledáte, by to mohlo být o něco snazší najít.

Chcete-li skutečně dostat všechno, co cestu a zabránit MySQL z „jít dál“, je třeba vyřešit problém vašeho připojení k bazénu udržet spojení otevřené příliš dlouho, a mimo kontrolu staré připojení pro vás.

Chcete-li získat nové připojení, můžete nastavit pool_recyclemožnost v create_enginehovoru. Tento příkaz je nastaven pool_recyclena počet sekund od začátku do fondu připojení mezi pokladnami, které chcete nové spojení, které mají být vytvořeny namísto existujícího spojení, které mají být vráceny.

Odpovězeno 24/06/2011 v 21:13
zdroj uživatelem

hlasů
6

Pokud používáte Flask-SQLAlchemy:

Vypadá to, že oprava je k dispozici: https://github.com/mitsuhiko/flask-sqlalchemy/issues/2

Je smutné, že výchozí instalace (pip nainstalovat baňka-sqlalchemy) se nevztahuje na opravu ještě správně, a to zejména v této otázce: https://github.com/e-dard/flask-sqlalchemy/commit/cf659f346e005d34257d256fa4c42889741fc31f

Získání nejnovější verzi z github měla opravit.

Odpovězeno 20/01/2013 v 12:41
zdroj uživatelem

hlasů
16

Měl jsem podobný problém, ale pro mě bych si jen ‚MySQL je pryč‘ chyba někde mezi 5 minutami a 2 hodinami každého zasedání.

Jsem pomocí Flask-SQLAlchemy, takže by to mělo zavřít nečinné připojení, ale nezdálo se, že dělá, že pokud spojení byl nečinný déle než pár hodin.

Nakonec jsem ji snížil na následující nastavení baňky-SQLAlchemy:

app.config['SQLALCHEMY_POOL_SIZE'] = 100
app.config['SQLALCHEMY_POOL_RECYCLE'] = 280

Výchozí nastavení se jedná o 10 až 7200 (2 hodiny), resp.

Jde o to, hrát si s tímto nastavením, aby se vešly vaše prostředí.

Například, že jsem četl na mnoha místech, která SQLALCHEMY_POOL_RECYCLE by měly být nastaveny na 3600, ale to není práce pro mě. Já hostování s PythonAnywhere a zabijí nečinné MySQL připojení po 5 minut (300 sekund). Takže nastavení mé hodnotu menší než 300 problém vyřešil.

Doufám, že to pomáhá ostatním, že jsem promarnil příliš mnoho času na toto téma.

http://flask-sqlalchemy.pocoo.org/2.1/config/#configuration-keys

Odpovězeno 05/03/2016 v 21:00
zdroj uživatelem

hlasů
11

2018 Odpověď: V SQLAlchemy v1.2.0 + máte připojení bazén pre-ping funkci k dispozici řešení tohoto problému na „MySQL server, je pryč.“

Spojení bazén pre-ping - Spojení bazénu nyní obsahuje volitelnou „pre ping“ funkci, která bude testovat „živosti“ v souhrnné připojení pro každého připojení pokladny, transparentně recyklace připojení DBAPI v případě, že databáze je odpojen. Tato funkce eliminuje potřebu „pool odpadkového“ vlajku, stejně jako o otázce chyb zvednutý, pokud je sdružená spojení používat po restartu databáze.

Pesimistické testování spojů na pokladně je možné s novým argumentem:

engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)
Odpovězeno 13/07/2017 v 11:12
zdroj uživatelem

hlasů
0

Nedávno jsem narazil na stejný problém a našel toto vlákno pomocí známých vyhledávačů. Četl jsem baňky a SQLAlchemy dokumenty o přesně toto téma, a následně je (myslím) do písmene, ale bezvýsledně.

Níže je fragment, který ilustruje svůj kódovací vzor. V podstatě je to takto:

  1. Vytvoření relace as scoped_session
  2. v každé cestě, otevřeno, použití a zavření Session ()
  3. Dělat teardown_appcontext věc (proč?)

Tady jsou:

from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker, scoped_session
import flask

engine = create_engine("mysql://....")
Session = scoped_session(sessionmaker(bind=engine))

app = flask.Flask(__name__)

@app.route('/')
def index():
    db = Session()
    # do stuff
    db.close()
    return flask.render_template('index.html')

@app.teardown_appcontext
def shutdown_session(exception=None):
    Session.remove()
Odpovězeno 14/06/2018 v 07:48
zdroj uživatelem

hlasů
0

Když jsem se setkal tuto chybu jsem ukládání LONGBLOB/ LargeBinaryimage ~ 1 MB ve velikosti. Musel jsem upravit max_allowed_packetnastavení konfiguračního v MySQL.

Použil jsem mysqld --max-allowed-packet=16M

Odpovězeno 25/06/2018 v 01:00
zdroj uživatelem

hlasů
0

Používáte-li bazén, měli byste nastavit recyle méně než wait_timeout DB wait_timeout 60. Tak jsem 40 až recyle

from sqlalchemy.pool import Pool
pool.QueuePool(self.get_connection, max_overflow=0,pool_size=40,recycle=50)
Odpovězeno 03/05/2019 v 13:18
zdroj uživatelem

hlasů
0

Pesimistické přístup, jak je popsáno @wim

pool_pre_ping = True

Nyní může být provedeno pro láhev-SQLAlchemy pomocí config var ->

SQLALCHEMY_POOL_PRE_PING = True

Odpovězeno 12/11/2019 v 18:03
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more