Рубрики
Без рубрики

Создание приложений React / Flask, которые подключаются к PostgreSQL и Harperdb

Я уверен, что большинство из вас уже более чем знакомы с стеком Мерн. Наличие реактивный фронт EN … Теги с JavaScript, WebDev, учебником, React.

Я уверен, что большинство из вас уже более чем знакомы с стеком Мерн. Наличие реактивный передний конец с помощью узла/экспресс-конца, который подключается к базе данных MongoDB. Ну, я покажу вам, насколько легко подключиться к задней части колбы, который использует базу данных PostgreSQL для сохранения данных. И как бонус, я даже покажу вам, как подключиться к https://harperdb.io/ Какой является платформой управления данными SQL/NOSQL. Он полностью проиндексирован, не дублирует данные и работает на любом устройстве с края в облако.

Предположим, что у вас уже есть понимание Python, Flask и SQL, поскольку это руководство предназначено для быстрого введения.

Вы будете создавать приложение, которое выглядит как изображение ниже.

Предварительные условия

  • Установлено приложение Insomnia или Postman API
  • NPM/Узел установлен на вашем компьютере
  • Python3 установлен и настройка
  • PostgreSQL установлен и настраивать
  • PIP3 установлен с установленными ниже пакетами ниже

https://pypi.org/project/Flask/

https://pypi.org/project/Flask-Cors/

https://pypi.org/project/python-dotenv/

https://pypi.org/project/psycopg2/ (включая двоичные файлы внизу) PIP Установите PSYCOPG2-двоичный

https://pypi.org/project/harperdb/

Создайте базу данных PostgreSQL

Для этого руководства я буду использовать Valentina Studio как GUI, чтобы управлять локальной PostgreSQL базой данных, которую вы можете найти здесь https://www.valentina-db.com/en/valentina-studio-overview Однако не стесняйтесь использовать любой инструмент, который вам нравится, вы можете даже использовать командную строку для взаимодействия с вашей базой данных, если вы предпочитаете.

Во-первых, создать базу данных под названием Metacritic А затем используйте SQL ниже изображений для создания таблицы, называемых фильмами.

CREATE TABLE movies (
    movie_id SERIAL PRIMARY KEY,
    movie_name VARCHAR(200) NOT NULL,
    img_url TEXT NOT NULL,
    release_year INT NOT NULL,
    summary TEXT NOT NULL,
    director VARCHAR(200) NOT NULL,
    genre VARCHAR(100) NOT NULL,
    rating VARCHAR(100) NOT NULL,
    movie_runtime INT NOT NULL,
    meta_score INT NOT NULL
)

Затем используйте SQL ниже изображения, чтобы добавить некоторые данные в таблицу фильмов.

INSERT INTO movies (movie_name, img_url, release_year, summary, director, genre, rating, movie_runtime, meta_score)
VALUES ('Casino Royale', 'https://static.metacritic.com/images/products/movies/9/08b5f3a45845fa3b6d1cb5f4978b5081-250h.jpg', 2006, 'After earning his license to kill James Bonds first 007 mission takes him to Madagascar where he is to spy on a terrorist. Not everything goes as planned and Bond decides to investigate independently of MI6.', 'Martin Campbell', 'Action', 'PG-13', 144, 80),('Tenet', 'https://static.metacritic.com/images/products/movies/7/a60818c40f69031bf30ca846444011e4-250h.jpg', 2020, 'Armed with only one word - Tenet - and fighting for the survival of the entire world the Protagonist (John David Washington) journeys through a twilight world of international espionage on a mission that will unfold in something beyond real time. Not time travel. Inversion.', 'Christopher Nolan', 'Action', 'PG-13', 150, 69),('Mulan', 'https://static.metacritic.com/images/products/movies/0/a496c3f832582876dc9b0d66197cab78-250h.jpg', 2020, 'When the Emperor of China issues a decree that one man per family must serve in the Imperial Army to defend the country from Northern invaders Hua Mulan the eldest daughter of an honored warrior steps in to take the place of her ailing father. Masquerading as a man Hua Jun she is tested every step of the way and must harness her inner-strength and embrace her true potential. It is an epic journey that will transform her into an honored warrior and earn her the respect of a grateful nation…and a proud father.', 'Niki Caro', 'Action', 'PG-13', 115, 67),('The Old Guard','https://static.metacritic.com/images/products/movies/7/b1db3c24db156b33c9fcfbbc199fcfcb-250h.jpg', 2020, 'Led by a warrior named Andy (Charlize Theron) a covert group of tight-knit mercenaries with a mysterious inability to die have fought to protect the mortal world for centuries. But when the team is recruited to take on an emergency mission and their extraordinary abilities are suddenly exposed it's up to Andy and Nile (Kiki Layne) the newest soldier to join their ranks to help the group eliminate the threat of those who seek to replicate and monetize their power by any means necessary.', 'Gina Prince-Bythewood', 'Action', 'R', 125, 70),('Greyhound', 'https://static.metacritic.com/images/products/movies/4/499215874bac5acda666be3659bacf7e-250h.jpg', 2020, 'In the early days of WWII an international convoy of 37 Allied ships led by captain Ernest Krause (Tom Hanks) in his first command of a U.S. destroyer crosses the treacherous North Atlantic while hotly pursued by wolf packs of Nazi U-boats.', 'Aaron Schneider', 'Action', 'PG-13', 91, 64),('The New Mutants', 'https://static.metacritic.com/images/products/movies/4/8fcef9e9a93457f7a0fdf2a51cf30a0d-250h.jpg', 2020, 'In an isolated hospital young mutants are being held for psychiatric monitoring. When strange occurrences begin to take place both their new mutant abilities and their friendships will be tested as they battle to try and make it out alive.', 'Josh Boone', 'Action', 'PG-13', 94, 43),('I Used to Go Here', 'https://static.metacritic.com/images/products/movies/5/9456ab11b0bd3b457f32c6c58157bf95-250h.jpg', 2020, 'Following the lackluster launch of her debut novel 35-year-old writer Kate Conklin (Gillian Jacobs) receives an invitation from her former professor and old crush (Jemaine Clement) to speak at her alma mater. With her book tour canceled and her ego deflated Kate decides to take the trip wondering if returning to her old college as a published author might give her the morale boost she sorely needs. Instead she falls into a comical regression – from misadventures with eccentric twenty-year-olds to feelings of jealousy toward her former professor's new favorite student. Striking the balance between bittersweet and hilarious Kate takes a journey through her past to redefine her future.', 'Kris Rey', 'Comedy', 'PG-13', 80, 68),('Hooking Up', 'https://static.metacritic.com/images/products/movies/0/fffb93ea39fcce7d65563163daa57c4c-250h.jpg', 2020, 'She (Brittany Snow) is an adventurous writer pumping out scandalous content for a lifestyle magazine. He (Sam Richardson) is a hopeless romantic who's just been dumped by his high school sweetheart and given a medical diagnosis that's left him shook. After a chance meeting the mismatched duo hit the road on a cross country trip to provide them both some much needed healing.', 'Nico Raineau', 'Drama', 'R', 104, 44),('Infamous', 'https://static.metacritic.com/images/products/movies/4/6da52f15b0fec577a53de1255cff6518-250h.jpg', 2020, 'Living in a small Florida town and working at a diner was never Arielles (Bella Thorne) dream life. Shes always wanted more. Fame. Popularity. Admiration. When she falls for a recently paroled young criminal named Dean she drags him back into a life of danger learning that posting their criminal exploits on social media is an easy way to viral fame. Obsessed with their rising number of followers they embark on a dangerous adventure together that leads to robbery cop chases and even murder. Heading to Hollywood the City of Stars they will realize what it takes to become famous and have to decide if this dangerous lifestyle is really worth it.', 'Joshua Caldwell', 'Drama', 'PG-13', 100, 40),('The LEGO Movie', 'https://static.metacritic.com/images/products/movies/7/55a09ad4264baf7d3e32b23a693d2307-250h.jpg', 2014, 'An ordinary LEGO minifigure, mistakenly thought to be the extraordinary MasterBuilder, is recruited to join a quest to stop an evil LEGO tyrant from gluing the universe together.', 'Christopher Miller and Phil Lord', 'Action', 'PG', 100, 83)

Запустите SQL ниже, чтобы увидеть все данные в таблицевых фильмах.

SELECT * FROM movies

Создайте конец колбы Сервер

Сначала перейдите в местоположение, похожее на ваш рабочий стол или папку, а затем используйте код ниже, чтобы настроить свой проект, используя приложение к терминалу.

Если у вас возникают проблемы с получением виртуальной среды для работы, прочитайте эту документацию https://docs.ython.org/3/library/venv.html.

mkdir meta-movies-app
cd meta-movies-app
python3 -m venv backend
. backend/bin/activate
cd backend
touch index.py

Откройте проект в своем редакторе кода, а затем создайте сервер Python/Flask в index.py файл

from flask import Flask


app = Flask(__name__)


@app.route('/')
def home():
    return 'Home Page Route'

Настройте среду разработки, запустив эти команды в вашем терминале.

export FLASK_APP=index.py   
export FLASK_ENV=development

Запустите приложение и перейдите в окно Browser, чтобы увидеть домашнюю страницу.

flask run

Подключиться к базе данных PostgreSQL

Во-первых, создать .gitignore файл и поместите его в корневую папку для бэкэки с кодом ниже внутри него

.env

Далее создайте .env Файл и положите его в корневую папку. Добавьте имя базы данных, имена пользователя и пароль, как в примере ниже. Я считаю, что имя пользователя всегда Postgres При работе с Postgres базы данных локально.

DATABASE="metacritic"
DATABASE_USERNAME="postgres"
DATABASE_PASSWORD="yourdatabasepassword"

Теперь обновите index.py Файл в корневой папке с кодом ниже.

from flask import Flask, jsonify
from flask_cors import CORS
from dotenv import load_dotenv
import psycopg2
import os

load_dotenv()

# PostgreSQL Database credentials loaded from the .env file
DATABASE = os.getenv('DATABASE')
DATABASE_USERNAME = os.getenv('DATABASE_USERNAME')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')

app = Flask(__name__)

# CORS implemented so that we don't get errors when trying to access the server from a different server location
CORS(app)


try:
    con = psycopg2.connect(
        database=DATABASE,
        user=DATABASE_USERNAME,
        password=DATABASE_PASSWORD)

    cur = con.cursor()

    # GET: Fetch all movies from the database
    @app.route('/')
    def fetch_all_movies():
        cur.execute('SELECT * FROM movies')
        rows = cur.fetchall()
        print(rows)

        return jsonify(rows)
except:
    print('Error')

Ваш сервер все еще должен работать, чтобы все, что вам нужно сделать, это перейти к окну браузера и перезагрузить страницу. Вы должны увидеть данные в вашей базе данных для табличных фильмов, возвращаемых в виде JSON, и данные также напечатаны в окне вашего терминала. Одно следует отметить, что данные возвращаются как кортеж Python, который выглядит как массив JavaScript. По сути, это выглядит как массив массивов, а не массив объектов, которые являются более распространенными. Это будет важно, когда мы доберемся до сечения передней части, и вы должны выводить данные в DOM.

Вы можете посмотреть документацию для пакета PSYCOPG2, чтобы узнать больше о коде https://www.psycopg.org/docs/

Реализация некоторой функциональности CRUD

Замените код в свой index.py Файл с кодом ниже. Теперь можно создавать, читать обновление и удаление данных из базы данных.

from flask import Flask, jsonify, request
from flask_cors import CORS
from dotenv import load_dotenv
import psycopg2
import os

load_dotenv()

# PostgreSQL Database credentials loaded from the .env file
DATABASE = os.getenv('DATABASE')
DATABASE_USERNAME = os.getenv('DATABASE_USERNAME')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')

app = Flask(__name__)

# CORS implemented so that we don't get errors when trying to access the server from a different server location
CORS(app)


try:
    con = psycopg2.connect(
        database=DATABASE,
        user=DATABASE_USERNAME,
        password=DATABASE_PASSWORD)

    cur = con.cursor()

    # GET: Fetch all movies from the database
    @app.route('/')
    def fetch_all_movies():
        cur.execute('SELECT * FROM movies')
        rows = cur.fetchall()
        print(rows)

        return jsonify(rows)

    # GET: Fetch movie by movieId from the database
    @app.route('/')
    def fetch_by_id(movie_id=None):
        cur.execute(f'SELECT * FROM movies WHERE movie_id = {movie_id}')
        rows = cur.fetchall()
        print(rows)

        return jsonify(rows)

    # POST: Create movies and add them to the database
    @app.route('/add-movie', methods=['GET', 'POST'])
    def add_movie():
        if request.method == 'POST':
            data = request.form.to_dict()
            print(data)
            cur.execute("INSERT INTO movies (movie_name, img_url, release_year, summary, director, genre, rating, movie_runtime, meta_score) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
                        (f"{data['movieName']}", f"{data['imgUrl']}", data['releaseYear'], f"{data['summary']}",
                         f"{data['director']}", f"{data['genre']}", f"{data['rating']}", data['movieRuntime'], data['metaScore']))
            con.commit()
            return 'Form submitted'
        else:
            return 'Form submission failed'

    # DELETE: Delete movie by movieId from the database
    @app.route('/delete-movie', methods=['GET', 'DELETE'])
    def delete_by_id():
        movie_id = request.form.to_dict()
        print(movie_id['movieId'])
        cur.execute(
            f"DELETE FROM movies WHERE movie_id = {movie_id['movieId']} RETURNING movie_name")
        con.commit()

        return 'Movie Deleted'

    # PUT: Update movie by movieId from the database
    @app.route('/update-movie', methods=['GET', 'PUT'])
    def update_by_id():

        cur.execute(
            'UPDATE movies SET movie_name = \'Goldeneye\' WHERE movie_id = 1')
        con.commit()

        return 'Movie Updated'

except:
    print('Error')

Использование инструмента API для проверки различных конечных точек

В этом руководстве я буду использовать приложение Insomnia API для выполнения различных запросов CRUD. Используйте скриншоты в качестве примера, чтобы увидеть его работать на вашем компьютере.

Получить: извлечь все фильмы из базы данных

Просто пойти в http://127.0.0.1:5000/ и нажмите Отправить, чтобы увидеть все данные базы данных, возвращенные как JSON

Get: Fetch Cline by MovieIn из базы данных

Просто пойти в http://127.0.0.1:5000/1 И ударить отправить, чтобы увидеть фильм, который соответствует этому идентификатору, возвращенному как JSON. Он будет работать с любым идентификационным номером, если он находится в базе данных.

СООБЩЕНИЕ: Создавайте фильмы и добавьте их в базу данных

Отправить сообщение запроса на http://127.0.0.1:5000/add-movie С помощью данных ключа Value Pair отображаются в примере скриншота. Затем отправляйтесь в Fetch все фильмы, чтобы увидеть новую запись. Кроме того, вы можете просто использовать вашу базу данных GUI или CLI, чтобы увидеть новую запись базы данных.

Удалить: Удалить фильм by jovieiv из базы данных

Отправить Удалить запрос на маршрут http://127.0.0.1:5000/delete-movie Использование имени MovieId. А также Поскольку значение использует любой идентификатор, который находится в базе данных, чтобы удалить эту запись.

ПОМЕЩАТЬ: Обновите фильм от MovieIn из базы данных

Просто отправляйся в http://127.0.0.1:5000/update-movie Использование вашего приложения API или в браузере, чтобы сделать обновление в запись базы данных. Перейти к нижней части index.py Файл, чтобы увидеть код для обновления маршрута. Вы можете изменить запрос SQL, чтобы обновить любой из полей в таблице, а затем все, что вам нужно сделать, это выбрать movie_id для обновления его записи. Вы можете увидеть код Python и SQL-запрос ниже.

Питон

# PUT: Update movie by movieId from the database
    @app.route('/update-movie', methods=['GET', 'PUT'])
    def update_by_id():

        cur.execute(
            'UPDATE movies SET movie_name = \'Goldeneye\' WHERE movie_id = 1')
        con.commit()

        return 'Movie Updated'

SQL.

UPDATE movies SET movie_name = 'Goldeneye'
WHERE movie_id = 1

Хорошо сделано, вы только что создали приложение Flask, которое подключается к базе данных PostgreSQL. Следующий раздел будет про harperdb.

Создать Harprdb. База данных

Сначала вам нужно создать учетную запись HarperDB, а затем создать базу данных. Я позвонил в мою базу данных “фильмы”. Создание и настройка Harprdb База данных очень проста. Просто следуйте этим видео Harperdb Cloud Launch Tour И вы также можете взглянуть на документацию для пакета Harperdb Python здесь https://pypi.org/project/harperdb/ .

Учетные данные

Вам может понадобиться код авторизации для подключения к HarperDB и если это так, это то, как вы его найдете. Сначала используйте свой инструмент API, чтобы отправить запрос на ваш URL HarperDB с вашим именем пользователя и паролем. Вам нужно использовать Basic Auth. Затем используйте кнопку «Создать код» и выберите Node.js и http, вы найдете код авторизации в коде заголовков. Изображения ниже показывают вам, как это сделано.

Подключение к Harperdb.

Как только вы настроите, убедитесь, что вы обновите свой .env Файл с вашими учетными данными Harperdb, как ниже.

DATABASE="metacritic"
DATABASE_USERNAME="postgres"
DATABASE_PASSWORD="yourdatabasepassword"
HARPERDB_URL="https://yourdatabase.harperdbcloud.com/"
HARPERDB_USERNAME="admin"
HARPERDB_PASSWORD="yourpassword"

Теперь обновите свой index.py Файл с кодом ниже. Мы импортировали HarperDB, учетные данные базы данных для него, а также создавали маршруты, которые вы можете найти внизу с полными запросами CRUD.

from flask import Flask, jsonify, request
from flask_cors import CORS
from dotenv import load_dotenv
import psycopg2
import os
import harperdb

load_dotenv()

# PostgreSQL Database credentials loaded from the .env file
DATABASE = os.getenv('DATABASE')
DATABASE_USERNAME = os.getenv('DATABASE_USERNAME')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')

# HarperDB Database credentials loaded from the .env file
HARPERDB_URL = os.getenv('HARPERDB_URL')
HARPERDB_USERNAME = os.getenv('HARPERDB_USERNAME')
HARPERDB_PASSWORD = os.getenv('HARPERDB_PASSWORD')

db = harperdb.HarperDB(
    url=HARPERDB_URL,
    username=HARPERDB_USERNAME,
    password=HARPERDB_PASSWORD)

app = Flask(__name__)

# CORS implemented so that we don't get errors when trying to access the server from a different server location
CORS(app)


try:
    con = psycopg2.connect(
        database=DATABASE,
        user=DATABASE_USERNAME,
        password=DATABASE_PASSWORD)

    cur = con.cursor()

    # GET: Fetch all movies from the database
    @app.route('/')
    def fetch_all_movies():
        cur.execute('SELECT * FROM movies')
        rows = cur.fetchall()
        print(rows)

        return jsonify(rows)

    # GET: Fetch movie by movieId from the database
    @app.route('/')
    def fetch_by_id(movie_id=None):
        cur.execute(f'SELECT * FROM movies WHERE movie_id = {movie_id}')
        rows = cur.fetchall()
        print(rows)

        return jsonify(rows)

    # POST: Create movies and add them to the database
    @app.route('/add-movie', methods=['GET', 'POST'])
    def add_movie():
        if request.method == 'POST':
            data = request.form.to_dict()
            print(data)
            cur.execute("INSERT INTO movies (movie_name, img_url, release_year, summary, director, genre, rating, movie_runtime, meta_score) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
                        (f"{data['movieName']}", f"{data['imgUrl']}", data['releaseYear'], f"{data['summary']}",
                         f"{data['director']}", f"{data['genre']}", f"{data['rating']}", data['movieRuntime'], data['metaScore']))
            con.commit()
            return 'Form submitted'
        else:
            return 'Form submission failed'

    # DELETE: Delete movie by movieId from the database
    @app.route('/delete-movie', methods=['GET', 'DELETE'])
    def delete_by_id():
        movie_id = request.form.to_dict()
        print(movie_id['movieId'])
        cur.execute(
            f"DELETE FROM movies WHERE movie_id = {movie_id['movieId']} RETURNING movie_name")
        con.commit()

        return 'Movie Deleted'

    # PUT: Update movie by movieId from the database
    @app.route('/update-movie', methods=['GET', 'PUT'])
    def update_by_id():

        cur.execute(
            'UPDATE movies SET movie_name = \'Goldeneye\' WHERE movie_id = 1')
        con.commit()

        return 'Movie Updated'

    # HarperDB Database routes

    # GET: Fetch all movies from the database
    @app.route('/harperdb')
    def harperdb_fetch_all():
        fetch_all = db._sql('SELECT * FROM dev.movies')
        print(fetch_all)
        return jsonify(fetch_all)

    # GET: Fetch movie by movieId from the database
    @app.route('/harperdb/')
    def harperdb_fetch_by_id(movie_id=None):
        # For fetching ID's that are numbers
        fetch_by_id = db._sql(
            f"SELECT * FROM dev.movies WHERE id = {movie_id}")

        # For fetching ID's that are strings
        # fetch_by_id = db._sql(
        #     f"SELECT * FROM dev.movies WHERE id = '{movie_id}'")
        print(fetch_by_id)
        return jsonify(fetch_by_id)

    # POST: Create movies and add them to the database
    @app.route('/harperdb/add-movie', methods=['GET', 'POST'])
    def harperdb_add_movie():
        if request.method == 'POST':
            data = request.form.to_dict()
            print(data)

            (f"{data['movieName']}", f"{data['imgUrl']}", data['releaseYear'], f"{data['summary']}",
             f"{data['director']}", f"{data['genre']}", f"{data['rating']}", data['movieRuntime'], data['metaScore'])
            add_new_movie = db._sql(
                f"INSERT INTO dev.movies(movie_name, img_url, release_year, summary, director, genre, rating, movie_runtime, meta_score) VALUES('{data['movieName']}', '{data['imgUrl']}', {data['releaseYear']}, '{data['summary']}', '{data['director']}', '{data['genre']}', '{data['rating']}', {data['movieRuntime']}, {data['metaScore']})")
            print(add_new_movie)
            return 'Form submitted'
        else:
            return 'Form submission failed'

    # DELETE: Delete movie by movieId from the database
    @app.route('/harperdb/delete-movie', methods=['GET', 'DELETE'])
    def harperdb_delete_by_id():
        movie_id = request.form.to_dict()
        print(movie_id['movieId'])
        # For fetching ID's that are numbers
        db._sql(
            f"DELETE FROM dev.movies WHERE id = {movie_id['movieId']}")

        # For fetching ID's that are strings
        # db._sql(
        #     f"DELETE FROM dev.movies WHERE id = '{movie_id['movieId']}'")

        return 'Movie Deleted'

    # PUT: Update movie by movieId from the database
    @app.route('/harperdb/update-movie', methods=['GET', 'PUT'])
    def harperdb_update_by_id():

        # For fetching ID's that are numbers
        db._sql(
            'UPDATE dev.movies SET movie_name = \'Goldeneye\' WHERE id = 7')

        # For fetching ID's that are strings
        # db._sql(
        #     f"UPDATE dev.movies SET movie_name = \'Goldeneye\' WHERE id = '42e7603f-f7ee-413d-9a0b-384ef04ca7de'")

        return 'Movie Updated'

except:
    print('Error')

Используйте свой инструмент API или ознакомьтесь с маршрутами в браузере, чтобы увидеть данные, возвращаемые как JSON из экземпляра базы данных Harperdb. Harperdb Магазины ID как строки, поэтому, пожалуйста, имейте в виду, что вы не сможете получать, обновлять и удалять фильм на MovieId, если его идентификатор номер, если вы не внесите некоторые настройки в свой код. Мы храним наш идентификатор как цифры, однако, легко переключаться между двумя, которые я прокомментировал примеры в коде.

Возможно, вам может потребоваться перезапустить Flask Server, если маршруты не работают на первой попытки.

Строить передний конец

Пришло время создать передний конец, который получит данные от API. CD В корневую папку для Meta-flaph-приложения, а затем запустить команду ниже, чтобы настроить проект в реакции.

npx create-react-app frontend
cd frontend

Теперь запустите сервер App App, используя либо NPM начать или пряжа Начало

Перейдите внутрь вашего проекта React, а затем удалите все CSS внутри index.csss файл. Затем замените код внутри App.csss и App.js Файлы с кодом ниже.

App.csss.

@import url('https://fonts.googleapis.com/css2?family=Arsenal:wght@400;700&display=swap');
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

html {
    font-size: 62.5%;
}

body {
    font-size: 1.6rem;
    font-family: 'Arsenal', sans-serif;
    /* letter-spacing: 0.2rem; */
    background: rgb(242, 242, 242);
    color: #0e0e0e;
}

header {
    background: #0e0e0e;
    padding: 1rem;
}

header h1 {
    margin: 0 auto;
    text-align: center;
    text-transform: uppercase;
    color: #ffffff;
}

section {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-evenly;
    margin: 4rem;
}

.form-container {
    margin: 2rem auto;
    width: 50rem;
    max-width: 100%;
    padding: 0 2rem 0 2rem;
}

form {
    display: flex;
    flex-flow: column;
}

form input {
    height: 3rem;
    padding: 1.5rem;
}

form textarea {
    padding: 1.5rem;
}

form button {
    padding: 1rem;
    border: none;
    background: #fcee0b;
    font-weight: bold;
    cursor: pointer;
    transition: background 0.3s;
    text-transform: uppercase;
}

form button:hover {
    background: rgb(243, 212, 35);
}

form div {
    display: flex;
    flex-flow: column;
    margin-bottom: 1.3rem;
}

.movie-container {
    background: #fcee0b;
    padding: 4rem;
    margin-top: 2rem;
    border-radius: 2rem 7rem;
    width: 50rem;
    max-width: 100%;
}

.movie-container h1 {
    font-size: 3rem;
}

.movie-container p {
    margin: 1rem 0 1rem 0;
    font-size: 2rem;
}

.movie-container img {
    width: 10rem;
    height: 15rem;
}

.high {
    background: #66cc32;
    width: 4rem;
    color: #ffffff;
    text-align: center;
    font-weight: 700;
    display: inline-block;
    padding: 0.5rem;
    border-radius: 1rem;
}

.medium {
    background: #ffcc32;
    width: 4rem;
    color: #ffffff;
    text-align: center;
    font-weight: 700;
    display: inline-block;
    padding: 0.5rem;
    border-radius: 1rem;
}

.low {
    background: #ff0100;
    width: 4rem;
    color: #ffffff;
    text-align: center;
    font-weight: 700;
    display: inline-block;
    padding: 0.5rem;
    border-radius: 1rem;
}

@media screen and (max-width: 1094px) {
    section {
        justify-content: center;
        /* margin: 0 auto; */
    }
}

App.js.

import React, { Fragment, useState, useEffect } from 'react';
import './App.css';

const App = () => {
    useEffect(() => {
        const getAPI = () => {
            // Change this endpoint to whatever local or online address you have
            // Local PostgreSQL Database
            const API = 'http://127.0.0.1:5000/';

            fetch(API)
                .then((response) => {
                    console.log(response);
                    return response.json();
                })
                .then((data) => {
                    console.log(data);
                    setLoading(false);
                    setApiData(data);
                });
        };
        getAPI();
    }, []);
    const [apiData, setApiData] = useState([]);
    const [loading, setLoading] = useState(true);
    return (
        
            

Meta Movie Reviews

Add Movie

{loading === true ? (

Loading...

) : (
{apiData.map((movie) => { const movieId = movie[0]; const movieName = movie[1]; const movieImgUrl = movie[2]; const movieReleaseYear = movie[3]; const movieSummary = movie[4]; const movieDirector = movie[5]; const movieGenre = movie[6]; const movieRating = movie[7]; const movieRuntime = movie[8]; const movieMetaScore = movie[9]; let metaColor = 'low'; if (movieMetaScore >= 70) { metaColor = 'high'; } else if (movieMetaScore <= 69 && movieMetaScore >= 49) { metaColor = 'medium'; } else { metaColor = 'low'; } return (

{movieName}

Director: {movieDirector}

Genre: {movieGenre}

{movieName}

Meta Score: {movieMetaScore}

Runtime: {movieRuntime}

Rating: {movieRating}

Release Year: {movieReleaseYear}

{movieSummary}

); })}
)}
); }; export default App;

Убедитесь, что ваш сервер Flask также работает. Вы должны увидеть приложение, работающее внутри вашего браузера. Он также имеет форму, которая позволяет добавлять новые записи базы данных, которые автоматически отображаются на странице. Мета-баллы даже в цвете кодированы в зависимости от их номера, который выполняется с использованием оператора, если вы можете видеть в коде.

Приложение подключено к вашей локальной базе данных PostgreSQL, однако, достаточно легко изменить конечную точку для API в Harperdb. Все другие маршруты находятся на заднем конце, чтобы вы могли играть с ними и подключить их к передней части, который я уверен, что вы уже способны делать.

Когда вы добавляете новый фильм, он не перенаправляется обратно к домашней странице реагирования. Если вы хотите добавить эту функцию, то обновите функцию вашего пост-маршрута на Backend index.py В разделе PostgreSQL файла с кодом ниже.

from flask import Flask, jsonify, request, redirect

# POST: Create movies and add them to the database
    @app.route('/add-movie', methods=['GET', 'POST'])
    def add_movie():
        if request.method == 'POST':
            data = request.form.to_dict()
            print(data)
            cur.execute("INSERT INTO movies (movie_name, img_url, release_year, summary, director, genre, rating, movie_runtime, meta_score) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)",
                        (f"{data['movieName']}", f"{data['imgUrl']}", data['releaseYear'], f"{data['summary']}",
                         f"{data['director']}", f"{data['genre']}", f"{data['rating']}", data['movieRuntime'], data['metaScore']))
            con.commit()
            # return 'Form submitted'
            return redirect('http://localhost:3000', code="200")
        else:
            return 'Form submission failed'

Оригинал: “https://dev.to/andrewbaisden/creating-react-flask-apps-that-connect-to-postgresql-and-harperdb-1op0”