Database
 sql >> Baza danych >  >> RDS >> Database

Flask by Example — konfiguracja Postgres, SQLAlchemy i Alembic

W tej części skonfigurujemy bazę danych Postgres do przechowywania wyników naszej liczby słów, a także SQLAlchemy, Object Relational Mapper i Alembic do obsługi migracji baz danych.

Bezpłatny bonus: Kliknij tutaj, aby uzyskać dostęp do bezpłatnego samouczka wideo Flask + Python, który pokazuje, jak krok po kroku zbudować aplikację internetową Flask.

Aktualizacje:

  • 02.09.2020:Aktualizacja do wersji Pythona 3.8.1 oraz najnowszych wersji Psycopg2, Flask-SQLAlchemy i Flask-Migrate. Zobacz poniżej szczegóły. Jawnie zainstaluj i używaj Flask-Script ze względu na zmianę wewnętrznego interfejsu Flask-Migrate.
  • 22.03.2016:Aktualizacja do wersji Pythona 3.5.1 oraz najnowszych wersji Psycopg2, Flask-SQLAlchemy i Flask-Migrate. Zobacz poniżej szczegóły.
  • 22.02.2015:Dodano obsługę Pythona 3.

Pamiętaj:oto, co tworzymy – aplikacja Flask, która oblicza pary słowo-częstotliwość na podstawie tekstu z danego adresu URL.

  1. Część pierwsza:skonfiguruj lokalne środowisko programistyczne, a następnie wdroż zarówno środowisko pomostowe, jak i produkcyjne w Heroku.
  2. Część druga:skonfiguruj bazę danych PostgreSQL wraz z SQLAlchemy i Alembic do obsługi migracji. (aktualny )
  3. Część trzecia:dodaj logikę zaplecza, aby zeskrobać, a następnie przetworzyć liczbę słów ze strony internetowej za pomocą bibliotek żądań, BeautifulSoup i Natural Language Toolkit (NLTK).
  4. Część czwarta:Zaimplementuj kolejkę zadań Redis do obsługi przetwarzania tekstu.
  5. Część piąta:skonfiguruj Angular na froncie, aby stale odpytywać zaplecze, aby sprawdzić, czy żądanie zostało przetworzone.
  6. Część szósta:Prześlij na serwer pomostowy w Heroku – konfiguracja Redis i szczegółowe omówienie sposobu uruchamiania dwóch procesów (sieciowego i roboczego) na jednym Dyno.
  7. Część siódma:zaktualizuj interfejs, aby był bardziej przyjazny dla użytkownika.
  8. Część ósma:Utwórz niestandardową dyrektywę kątową, aby wyświetlić wykres rozkładu częstotliwości za pomocą JavaScript i D3.

Potrzebujesz kodu? Pobierz go z repozytorium.


Wymagania dotyczące instalacji

Narzędzia użyte w tej części:

  • PostgreSQL (11.6)
  • Psycopg2 (2.8.4) — adapter Pythona dla Postgresa
  • Flask-SQLAlchemy (2.4.1) - rozszerzenie Flask, które zapewnia obsługę SQLAlchemy
  • Flask-Migrate (2.5.2) - rozszerzenie obsługujące migracje baz danych SQLAlchemy przez Alembic

Aby rozpocząć, zainstaluj Postgres na swoim lokalnym komputerze, jeśli jeszcze go nie masz. Ponieważ Heroku korzysta z Postgresa, dobrze będzie, jeśli będziemy rozwijać się lokalnie na tej samej bazie danych. Jeśli nie masz zainstalowanego Postgresa, Postgres.app to łatwy sposób na uruchomienie i uruchomienie dla użytkowników Mac OS X. Więcej informacji znajdziesz na stronie pobierania.

Po zainstalowaniu i uruchomieniu Postgresa utwórz bazę danych o nazwie wordcount_dev do wykorzystania jako nasza lokalna baza danych deweloperskich:

$ psql
# create database wordcount_dev;
CREATE DATABASE
# \q

Aby korzystać z naszej nowo utworzonej bazy danych w aplikacji Flask, musimy zainstalować kilka rzeczy:

$ cd flask-by-example

cd Wejście do katalogu powinno aktywować środowisko wirtualne i ustawić zmienne środowiskowe znajdujące się w .env plik przez autoenv, który ustawiliśmy w części 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

Jeśli korzystasz z OS X i masz problemy z instalacją psycopg2, zapoznaj się z tym artykułem Stack Overflow.

Może być konieczne zainstalowanie psycopg2-binary zamiast psycopg2 jeśli instalacja się nie powiedzie.



Aktualizuj konfigurację

Dodaj SQLALCHEMY_DATABASE_URI pole do Config() klasę w pliku config.py plik, aby ustawić aplikację tak, aby korzystała z nowo utworzonej bazy danych w fazie rozwoju (lokalnie), pomostowej i produkcyjnej:

import os

class Config(object):
    ...
    SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']

Twój config.py plik powinien teraz wyglądać tak:

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

Teraz, gdy nasza konfiguracja zostanie załadowana do naszej aplikacji, odpowiednia baza danych zostanie również z nim połączona.

Podobnie jak dodaliśmy zmienną środowiskową w ostatnim poście, dodamy DATABASE_URL zmienny. Uruchom to w terminalu:

$ export DATABASE_URL="postgresql:///wordcount_dev"

A następnie dodaj tę linię do pliku .env plik.

W Twoim app.py plik zaimportuj SQLAlchemy i połącz się z bazą danych:

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()


Model danych

Skonfiguruj podstawowy model, dodając models.py plik:

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)

Tutaj stworzyliśmy tabelę do przechowywania wyników liczenia słów.

Najpierw importujemy połączenie z bazą danych, które utworzyliśmy w naszym app.py oraz JSON z dialektów PostgreSQL firmy SQLAlchemy. Kolumny JSON są dość nowe w Postgresie i nie są dostępne w każdej bazie danych obsługiwanej przez SQLAlchemy, więc musimy je specjalnie zaimportować.

Następnie utworzyliśmy Result() klasy i przypisał jej nazwę tabeli results . Następnie ustawiamy atrybuty, które chcemy przechowywać dla wyniku-

  • id wyników, które zapisaliśmy
  • url że policzyliśmy słowa z
  • pełna lista słów, które policzyliśmy
  • lista słów, które policzyliśmy, minus słowa stop (więcej o tym później)

Następnie utworzyliśmy __init__() metoda, która zostanie uruchomiona za pierwszym razem, gdy utworzymy nowy wynik, a na koniec __repr__() metoda do reprezentowania obiektu, gdy o niego pytamy.



Migracja lokalna

Zamierzamy użyć Alembic, który jest częścią Flask-Migrate, do zarządzania migracjami baz danych w celu aktualizacji schematu bazy danych.

Uwaga: Flask-Migrate korzysta z nowego narzędzia CLI Flasks. Jednak ten artykuł korzysta z interfejsu udostępnionego przez Flask-Script, który był wcześniej używany przez Flask-Migrate. Aby z niego skorzystać, musisz go zainstalować za pomocą:

$ python -m pip install Flask-Script==2.0.6
$ python -m pip freeze > requirements.txt

Utwórz nowy plik o nazwie 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()

Aby korzystać z Flask-Migrate, zaimportowaliśmy Manager jak również Migrate i MigrateCommand do naszego manage.py plik. Zaimportowaliśmy również app i db więc mamy do nich dostęp z poziomu skryptu.

Najpierw ustawiamy naszą konfigurację tak, aby nasze środowisko — na podstawie zmiennej środowiskowej — tworzyło migrowaną instancję z app i db jako argumenty i skonfiguruj manager polecenie do zainicjowania manager przykład dla naszej aplikacji. Na koniec dodaliśmy db polecenie do manager abyśmy mogli uruchomić migracje z wiersza poleceń.

Aby uruchomić migracje, zainicjuj 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 uruchomieniu inicjalizacji bazy danych zobaczysz w projekcie nowy folder o nazwie „migracje”. To zawiera konfigurację niezbędną dla Alembic do uruchamiania migracji w projekcie. Wewnątrz „migrations” zobaczysz, że ma folder o nazwie „versions”, który będzie zawierał tworzone skrypty migracji.

Stwórzmy naszą pierwszą migrację, uruchamiając migrate polecenie.

$ 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

Teraz zauważysz, że w folderze „wersje” znajduje się plik migracji. Ten plik jest automatycznie generowany przez Alembic na podstawie modelu. Możesz samodzielnie wygenerować (lub edytować) ten plik; jednak w większości przypadków wystarczy automatycznie wygenerowany plik.

Teraz zastosujemy aktualizacje do bazy danych za pomocą db upgrade polecenie:

$ 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

Baza danych jest teraz gotowa do użycia w naszej aplikacji:

$ 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)


Zdalna migracja

Na koniec zastosujmy migracje do baz danych na Heroku. Najpierw jednak musimy dodać szczegóły baz danych pomostowych i produkcyjnych do config.py plik.

Aby sprawdzić, czy mamy skonfigurowaną bazę danych na serwerze pomostowym, uruchom:

$ heroku config --app wordcount-stage
=== wordcount-stage Config Vars
APP_SETTINGS: config.StagingConfig

Pamiętaj, aby zastąpić wordcount-stage z nazwą Twojej aplikacji testowej.

Ponieważ nie widzimy zmiennej środowiskowej bazy danych, musimy dodać dodatek Postgres do serwera pomostowego. Aby to zrobić, uruchom następujące polecenie:

$ 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 to darmowa warstwa dodatku Heroku Postgres.

Teraz, gdy uruchamiamy heroku config --app wordcount-stage ponownie powinniśmy zobaczyć ustawienia połączenia z bazą danych:

=== 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

Następnie musimy zatwierdzić zmiany, które wprowadziłeś w git i przesłać na serwer pomostowy:

$ git push stage master

Uruchom migracje, które utworzyliśmy w celu migracji naszej tymczasowej bazy danych za pomocą heroku run polecenie:

$ 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

Zwróć uwagę, że uruchomiliśmy tylko upgrade , a nie init lub migrate polecenia jak wcześniej. Mamy już skonfigurowany i gotowy do pracy plik migracji; wystarczy zastosować go do bazy danych Heroku.

Zróbmy teraz to samo dla produkcji.

  1. Skonfiguruj bazę danych dla aplikacji produkcyjnej w Heroku, tak jak w przypadku testowania:heroku addons:create heroku-postgresql:hobby-dev --app wordcount-pro
  2. Prześlij swoje zmiany do witryny produkcyjnej:git push pro master Zwróć uwagę, że nie musisz wprowadzać żadnych zmian w pliku konfiguracyjnym - ustawia on bazę danych na podstawie nowo utworzonego DATABASE_URL zmienna środowiskowa.
  3. Zastosuj migracje:heroku run python manage.py db upgrade --app wordcount-pro

Teraz zarówno nasze witryny testowe, jak i produkcyjne mają skonfigurowane bazy danych i są migrowane – i gotowe do pracy!

Po zastosowaniu nowej migracji do produkcyjnej bazy danych może wystąpić przestój. Jeśli jest to problem, możesz skonfigurować replikację bazy danych, dodając bazę danych „follower” (powszechnie znaną jako podrzędna). Więcej informacji na ten temat znajdziesz w oficjalnej dokumentacji Heroku.



Wniosek

To tyle w części 2. Jeśli chcesz zagłębić się w Flask, obejrzyj naszą towarzyszącą serię filmów:

Bezpłatny bonus: Kliknij tutaj, aby uzyskać dostęp do bezpłatnego samouczka wideo Flask + Python, który pokazuje, jak krok po kroku zbudować aplikację internetową Flask.

W części 3 zamierzamy zbudować funkcję liczenia słów i wysłać ją do kolejki zadań, aby poradzić sobie z dłużej działającym przetwarzaniem liczenia słów.

Do zobaczenia następnym razem. Pozdrawiam!

To dzieło powstałe dzięki współpracy Cam Linke, współzałożycielki Startup Edmonton, i ludzi z Real Pythona.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Prosta parametryzacja i trywialne plany — część 3

  2. Parsuj domyślne wartości parametrów za pomocą PowerShell – część 2

  3. Jaka jest średnia pensja programisty SQL?

  4. Co robi projektant baz danych?

  5. SQL Union — kompleksowy przewodnik po operatorze UNION