V této části nastavíme databázi Postgres pro ukládání výsledků našich počtů slov a také SQLAlchemy, Object Relational Mapper a Alembic pro zpracování migrací databáze.
Box zdarma: Kliknutím sem získáte přístup k bezplatnému videonávodu Flask + Python, který vám krok za krokem ukáže, jak vytvořit webovou aplikaci Flask.
Aktualizace:
- 02/09/2020:Upgradováno na Python verze 3.8.1 a také na nejnovější verze Psycopg2, Flask-SQLAlchemy a Flask-Migrate. Podrobnosti viz níže. Explicitně nainstalujte a použijte Flask-Script kvůli změně vnitřního rozhraní Flask-Migrate.
- 03/22/2016:Upgradováno na Python verze 3.5.1 a také na nejnovější verze Psycopg2, Flask-SQLAlchemy a Flask-Migrate. Podrobnosti naleznete níže.
- 22. 2. 2015:Přidána podpora Pythonu 3.
Pamatujte:Zde je to, co vytváříme – aplikaci Flask, která vypočítává dvojice slov a frekvence na základě textu z dané adresy URL.
- Část první:Nastavte místní vývojové prostředí a poté nasaďte pracovní i produkční prostředí na Heroku.
- Část druhá:Nastavení databáze PostgreSQL spolu s SQLAlchemy a Alembic pro zpracování migrací. (aktuální )
- Část třetí:Přidejte logiku back-endu pro seškrabování a následné zpracování počtu slov z webové stránky pomocí knihoven požadavků, BeautifulSoup a Natural Language Toolkit (NLTK).
- Čtvrtá část:Implementujte frontu úloh Redis pro zpracování textu.
- Část pátá:Nastavte Angular na front-endu, aby se průběžně dotazoval na back-endu, abyste zjistili, zda je zpracování dokončeno.
- Část šestá:Pusťte se na pracovní server na Heroku – nastavení Redis a podrobný popis, jak spustit dva procesy (webový a pracovní) na jednom Dyno.
- Část sedmá:Aktualizujte front-end, aby byl uživatelsky přívětivější.
- Část osmá:Vytvořte vlastní úhlovou směrnici pro zobrazení grafu rozdělení frekvence pomocí JavaScriptu a D3.
Potřebujete kód? Získejte to z úložiště.
Požadavky na instalaci
Nástroje použité v této části:
- PostgreSQL (11.6)
- Psycopg2 (2.8.4) – Python adaptér pro Postgres
- Flask-SQLAlchemy (2.4.1) – Rozšíření Flask, které poskytuje podporu SQLAlchemy
- Flask-Migrate (2.5.2) – rozšíření, které podporuje migraci databáze SQLAlchemy přes Alembic
Chcete-li začít, nainstalujte Postgres na místní počítač, pokud jej ještě nemáte. Protože Heroku používá Postgres, bude pro nás dobré vyvíjet lokálně na stejné databázi. Pokud nemáte nainstalovaný Postgres, Postgres.app je pro uživatele Mac OS X snadný způsob, jak začít pracovat. Další informace naleznete na stránce stahování.
Jakmile budete mít Postgres nainstalován a spuštěn, vytvořte databázi s názvem wordcount_dev
použít jako naši databázi místního rozvoje:
$ psql
# create database wordcount_dev;
CREATE DATABASE
# \q
Abychom mohli používat naši nově vytvořenou databázi v aplikaci Flask, musíme nainstalovat několik věcí:
$ cd flask-by-example
cd
Vstup do adresáře by měl aktivovat virtuální prostředí a nastavit proměnné prostředí nalezené v.env
soubor přes autoenv, který jsme nastavili v části 1.
$ python -m pip install psycopg2==2.8.4 Flask-SQLAlchemy===2.4.1 Flask-Migrate==2.5.2
$ python -m pip freeze > requirements.txt
Pokud používáte OS X a máte potíže s instalací psycopg2, podívejte se na tento článek Stack Overflow.
Možná budete muset nainstalovat
psycopg2-binary
místopsycopg2
pokud se instalace nezdaří.
Aktualizovat konfiguraci
Přidejte SQLALCHEMY_DATABASE_URI
do pole Config()
třídy ve vašem config.py soubor pro nastavení vaší aplikace tak, aby používala nově vytvořenou databázi při vývoji (lokálním), pracovním prostředí a produkci:
import os
class Config(object):
...
SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']
Vaše config.py soubor by nyní měl vypadat takto:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
DEBUG = False
TESTING = False
CSRF_ENABLED = True
SECRET_KEY = 'this-really-needs-to-be-changed'
SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']
class ProductionConfig(Config):
DEBUG = False
class StagingConfig(Config):
DEVELOPMENT = True
DEBUG = True
class DevelopmentConfig(Config):
DEVELOPMENT = True
DEBUG = True
class TestingConfig(Config):
TESTING = True
Nyní, když je naše konfigurace načtena do naší aplikace, bude k ní také připojena příslušná databáze.
Podobně jako jsme přidali proměnnou prostředí v posledním příspěvku, přidáme DATABASE_URL
variabilní. Spusťte toto v terminálu:
$ export DATABASE_URL="postgresql:///wordcount_dev"
A pak přidejte tento řádek do .env soubor.
Ve vašem app.py import souboru SQLAlchemy a připojení k databázi:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from models import Result
@app.route('/')
def hello():
return "Hello World!"
@app.route('/<name>')
def hello_name(name):
return "Hello {}!".format(name)
if __name__ == '__main__':
app.run()
Datový model
Nastavte základní model přidáním souboru models.py soubor:
from app import db
from sqlalchemy.dialects.postgresql import JSON
class Result(db.Model):
__tablename__ = 'results'
id = db.Column(db.Integer, primary_key=True)
url = db.Column(db.String())
result_all = db.Column(JSON)
result_no_stop_words = db.Column(JSON)
def __init__(self, url, result_all, result_no_stop_words):
self.url = url
self.result_all = result_all
self.result_no_stop_words = result_no_stop_words
def __repr__(self):
return '<id {}>'.format(self.id)
Zde jsme vytvořili tabulku pro uložení výsledků počtů slov.
Nejprve importujeme připojení k databázi, které jsme vytvořili v našem app.py stejně jako JSON z SQLAlchemy’s PostgreSQL dialektů. Sloupce JSON jsou pro Postgres poměrně nové a nejsou dostupné ve všech databázích podporovaných SQLAlchemy, takže je musíme importovat konkrétně.
Dále jsme vytvořili Result()
class a přiřadil jí název tabulky results
. Poté nastavíme atributy, které chceme uložit pro výsledek-
id
výsledku, který jsme uložiliurl
že jsme slova počítali z- úplný seznam slov, která jsme spočítali
- seznam slov, která jsme spočítali bez zastavovacích slov (více o tom později)
Poté jsme vytvořili __init__()
metoda, která se spustí, když poprvé vytvoříme nový výsledek, a nakonec __repr__()
metoda reprezentující objekt, když se na něj dotazujeme.
Místní migrace
Ke správě migrací databáze za účelem aktualizace schématu databáze použijeme Alembic, který je součástí Flask-Migrate.
Poznámka: Flask-Migrate využívá nový CLI nástroj Flasks. Tento článek však používá rozhraní poskytované Flask-Script, které bylo dříve používáno Flask-Migrate. Abyste jej mohli používat, musíte jej nainstalovat pomocí:
$ python -m pip install Flask-Script==2.0.6 $ python -m pip freeze > requirements.txt
Vytvořte nový soubor s názvem manage.py :
import os
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import app, db
app.config.from_object(os.environ['APP_SETTINGS'])
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
Abychom mohli používat Flask-Migrate, importovali jsme Manager
a také Migrate
a MigrateCommand
na náš manage.py soubor. Také jsme importovali app
a db
takže k nim máme přístup ze skriptu.
Nejprve jsme nastavili naši konfiguraci tak, aby naše prostředí – na základě proměnné prostředí – vytvořilo instanci migrace s app
a db
jako argumenty a nastavte manager
příkaz k inicializaci Manager
například pro naši aplikaci. Nakonec jsme přidali db
příkaz manager
abychom mohli spustit migraci z příkazového řádku.
Chcete-li spustit migraci, inicializujte Alembic:
$ python manage.py db init
Creating directory /flask-by-example/migrations ... done
Creating directory /flask-by-example/migrations/versions ... done
Generating /flask-by-example/migrations/alembic.ini ... done
Generating /flask-by-example/migrations/env.py ... done
Generating /flask-by-example/migrations/README ... done
Generating /flask-by-example/migrations/script.py.mako ... done
Please edit configuration/connection/logging settings in
'/flask-by-example/migrations/alembic.ini' before proceeding.
Po spuštění inicializace databáze uvidíte v projektu novou složku s názvem „migrations“. Toto obsahuje nastavení nezbytné pro Alembic ke spuštění migrací proti projektu. Uvnitř „migrations“ uvidíte, že má složku nazvanou „versions“, která bude obsahovat migrační skripty tak, jak jsou vytvořeny.
Vytvořme naši první migraci spuštěním migrate
příkaz.
$ python manage.py db migrate
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'results'
Generating /flask-by-example/migrations/versions/63dba2060f71_.py
... done
Nyní si všimnete, že ve složce „verze“ je soubor migrace. Tento soubor automaticky generuje Alembic na základě modelu. Tento soubor můžete vygenerovat (nebo upravit) sami; nicméně ve většině případů postačí automaticky vygenerovaný soubor.
Nyní použijeme upgrady na databázi pomocí db upgrade
příkaz:
$ python manage.py db upgrade
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 63dba2060f71, empty message
Databáze je nyní připravena k použití v naší aplikaci:
$ psql
# \c wordcount_dev
You are now connected to database "wordcount_dev" as user "michaelherman".
# \dt
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+---------------
public | alembic_version | table | michaelherman
public | results | table | michaelherman
(2 rows)
# \d results
Table "public.results"
Column | Type | Modifiers
----------------------+-------------------+------------------------------------------------------
id | integer | not null default nextval('results_id_seq'::regclass)
url | character varying |
result_all | json |
result_no_stop_words | json |
Indexes:
"results_pkey" PRIMARY KEY, btree (id)
Vzdálená migrace
Nakonec aplikujme migraci na databáze na Heroku. Nejprve však musíme přidat podrobnosti o pracovních a produkčních databázích do config.py soubor.
Chcete-li zkontrolovat, zda máme databázi nastavenou na pracovním serveru, spusťte:
$ heroku config --app wordcount-stage
=== wordcount-stage Config Vars
APP_SETTINGS: config.StagingConfig
Nezapomeňte nahradit
wordcount-stage
s názvem vaší pracovní aplikace.
Protože nevidíme proměnnou prostředí databáze, musíme přidat doplněk Postgres na pracovní server. Chcete-li tak učinit, spusťte následující příkaz:
$ heroku addons:create heroku-postgresql:hobby-dev --app wordcount-stage
Creating postgresql-cubic-86416... done, (free)
Adding postgresql-cubic-86416 to wordcount-stage... done
Setting DATABASE_URL and restarting wordcount-stage... done, v8
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Use `heroku addons:docs heroku-postgresql` to view documentation.
hobby-dev
je bezplatná úroveň doplňku Heroku Postgres.
Nyní, když spustíme heroku config --app wordcount-stage
znovu bychom měli vidět nastavení připojení k databázi:
=== wordcount-stage Config Vars
APP_SETTINGS: config.StagingConfig
DATABASE_URL: postgres://azrqiefezenfrg:Zti5fjSyeyFgoc-U-yXnPrXHQv@ec2-54-225-151-64.compute-1.amazonaws.com:5432/d2kio2ubc804p7
Dále musíme potvrdit změny, které jste provedli v git a odeslat na váš pracovní server:
$ git push stage master
Spusťte migrace, které jsme vytvořili za účelem migrace naší zkušební databáze, pomocí heroku run
příkaz:
$ heroku run python manage.py db upgrade --app wordcount-stage
Running python manage.py db upgrade on wordcount-stage... up, run.5677
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 63dba2060f71, empty message
Všimněte si, jak jsme spustili pouze
upgrade
, nikoliinit
nebomigrate
příkazy jako předtím. Náš migrační soubor již máme nastavený a připravený k použití; jen to musíme použít proti databázi Heroku.
Nyní udělejme totéž pro produkci.
- Nastavte databázi pro svou produkční aplikaci na Heroku, stejně jako jste to udělali pro přípravu:
heroku addons:create heroku-postgresql:hobby-dev --app wordcount-pro
- Přeneste změny na svůj produkční web:
git push pro master
Všimněte si, že v konfiguračním souboru nemusíte provádět žádné změny – nastavuje databázi na základě nově vytvořenéDATABASE_URL
proměnná prostředí. - Použijte migrace:
heroku run python manage.py db upgrade --app wordcount-pro
Nyní mají naše pracovní i produkční místa nastavené databáze a jsou migrovány – a připraveny k provozu!
Když použijete novou migraci na produkční databázi, může dojít k výpadku. Pokud se jedná o problém, můžete nastavit replikaci databáze přidáním databáze „následovníka“ (běžně známé jako podřízená). Více o tom najdete v oficiální dokumentaci Heroku.
Závěr
To je vše pro část 2. Pokud byste se chtěli do Flask ponořit hlouběji, podívejte se na naši doprovodnou sérii videí:
Box zdarma: Kliknutím sem získáte přístup k bezplatnému videonávodu Flask + Python, který vám krok za krokem ukáže, jak vytvořit webovou aplikaci Flask.
V části 3 vytvoříme funkci počítání slov a necháme ji odeslat do fronty úkolů, abychom se vypořádali s déle běžícím zpracováním počítání slov.
Uvidíme se příště. Na zdraví!
Toto je spolupráce mezi Cam Linkem, spoluzakladatelem Startup Edmonton, a lidmi z Real Python.