HBase
 sql >> база данни >  >> NoSQL >> HBase

Създаване на Simple CRUD уеб приложение и магазин за изображения с помощта на Cloudera Operational Database и Flask

Оперативната база данни на Cloudera (COD) е управлявано dbPaaS решение, достъпно като опит в Cloudera Data Platform (CDP). Той предлага мултимодален клиентски достъп с NoSQL ключ-стойност, използвайки Apache HBase API и релационен SQL с JDBC (чрез Apache Phoenix). Последното прави COD достъпен за разработчици, които са свикнали да създават приложения, които използват MySQL, Postgres и др. Основните предимства на COD включват:

  • Автоматично мащабиране –  въз основа на използването на работното натоварване на клъстера и скоро ще има възможност за увеличаване/намаляване на клъстера
  • Автоматична настройка – по-добра производителност в рамките на съществуващата инфраструктура.
  • Автоматично заздравяване – разрешавайте оперативните проблеми автоматично (очаквайте скоро).

В този блог ще демонстрирам как COD може лесно да се използва като бекенд система за съхранение на данни и изображения за просто уеб приложение. За да създадем това приложение, ще използваме Phoenix, един от основните компоненти на COD, заедно с Flask. За съхраняване на изображения ще използваме възможност за HBase (задно съхранение на Apache Phoenix), наречена MOB (средни обекти). MOB ни позволява бързо да четем/записваме стойности от 100k-10MB.

*За улесняване на използване при разработка, можете също да използвате сървъра за заявки на Phoenix вместо COD. Сървърът за заявки е малка версия на phoenix, която е предназначена само за целите на разработката и данните се изтриват при всяка компилация.

Целият код е в моето репо на github.

Инструкции:

1. Влезте в конзолата за управление на Cloudera и изберете опит с оперативна база данни

2. Изберете вашата среда и наименувайте вашата DB

3. След като DB е готов, вземете URL от тънкия JDBC клиент

4. Задайте вашата парола за CDP за натоварване

5. Клонирайте проект git repo и изисквания за инсталиране:$ pip install -r requirements.txt

6. Отидете в папката на приложението и стартирайте “setup.py” – това ще създаде таблица с 3 записа на потребители и техните изображения $ python setup.py

7. Стартирайте уеб сървъра flask за стартиране на уеб приложението:$ FLASK_APP=app.py python -m flask run –port=8888 –host=127.0.0.1  –reload –with-threads –debugger

8. Отидете на http://localhost:8888/users във вашия браузър. Трябва да можете да видите как приложението работи! Просто толкова.

Преминаване през Кодекса

1. Класът Schema,  по принцип съдържа подробностите за връзката и методите за създаване и пускане на таблица. Както можете да видите, колоната „снимка“ е тип VARBINARY, който се превежда в MOB обект в HBase:

import phoenixdb
import phoenixdb.cursor
class Schema:
    def __init__(self):
        opts = {}
        opts['authentication'] = 'BASIC'
        opts['avatica_user'] = '<cod workload username>'
        opts['avatica_password'] = '<cod workload pw>'
        database_url = "<cod thin jdbc url>"
        self.TABLENAME = "users"
        self.conn = phoenixdb.connect(database_url, autocommit=True,**opts)
        self.curs = self.conn.cursor()

    def create_users_table(self):
        query = """
        CREATE TABLE IF NOT EXISTS """+self.TABLENAME+""" (
        username VARCHAR NOT NULL,
        firstname VARCHAR,
        lastname  VARCHAR,
        telephone VARCHAR,
        message VARCHAR,
        email VARCHAR,
        photo VARBINARY,
        photo_name VARCHAR,
        photo_type VARCHAR,
        photo_chars VARCHAR
        CONSTRAINT my_pk PRIMARY KEY (username))
        """
        self.curs.execute(query)

    def drop_users_table(self):
        query = "DROP TABLE "+self.TABLENAME
        self.curs.execute(query)

2 Потребителският клас е отговорен за всички операции на приложението с Phoenix. Можем да актуализираме/вмъкваме (upsert на език Phoenix), изтриваме, изброяваме и обработваме транзакции с изображения:

import phoenixdb
from schema import Schema
import json
class UsersModel:
    TABLENAME = "users"

    def __init__(self):
        db = Schema()
        self.conn=db.conn
        self.curs=db.curs

    def upsert(self, params):

        sql = "upsert into " + self.TABLENAME + \
            " (username ,message,telephone,firstname,lastname,email) \
             values (?,?,?,?,?,?)"
        data = (params.get('username'),params.get('message'),\
            params.get('telephone'),params.get('firstname'),\
            params.get('lastname'),params.get('email'))
        results = self.curs.execute(sql,data)
        return results

    def upsert_photo(self, params):
        if params.get('photo') is None:
            photo = bytes('','utf-8')
        else:
            photo = params.get('photo')

        sql = "upsert into " + self.TABLENAME + \
            " (username, photo,photo_name) values (?,?,?)"

        data = (params.get('username'),photo, params.get('photo_name'))
        results = self.curs.execute(sql,data)
        return results

    def delete(self, username):
        query = f"DELETE from {self.TABLENAME} " \
                f"WHERE username = {username}"

        self.curs.execute(query)

    def list_items(self, where_clause="",format="json"):
        query = f"SELECT username ,email,message,telephone,firstname,\
            lastname,photo_name " \
            f"from {self.TABLENAME} WHERE  " + where_clause

        self.curs.execute(query)
        if format=="json":
            r = [dict((self.curs.description[i][0].lower(), value) \
                   for i, value in enumerate(row)) for row in \
                   self.curs.fetchall()]
            self.conn.close()
            data={'data': r }
            return json.dumps(data)

        result_set=self.curs.fetchall()
        result = [{column: row[i]
            for i, column in enumerate(result_set[0].keys())}
                for row in result_set]
        return result
    def get_image(self, username):
        query = f"SELECT photo,photo_name " \
                f"from {self.TABLENAME} WHERE  username='"+username+"'"

        self.curs.execute(query)
        row = self.curs.fetchone()
        return row

3. App.py е основният рутер за приложението. Той съдържа цялата обработка с потребителски входове и насочването им към методите за свързване. Отделих обработката на изображения за по-лесно използване и по този начин мога да получа конкретно изображение за потребител:

from flask import Flask, request, send_file ,jsonify,render_template
import phoenixdb
import io
from users import UsersModel
from schema import Schema
import json

app = Flask(__name__)

@app.after_request
def add_headers(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Headers'] =  \
        "Content-Type, Access-Control-Allow-Headers, Authorization, \
        X-Requested-With"
    response.headers['Access-Control-Allow-Methods']=  "POST, GET, PUT, \
    DELETE, OPTIONS"
    response.headers['Allow']=  "POST, GET, PUT, OPTIONS"
    return response

@app.route("/")
def hello():
    return "Hello World!"

@app.route("/users")
def return_form():
    return render_template("users.html")

@app.route("/handle_data",methods=['POST'])
def handle_data():
    if request.method == 'POST':
        username = request.form['username']
        firstname = request.form['firstname']
        lastname = request.form['lastname']
        email = request.form['email']
        telephone = request.form['telephone']
        message = request.form['message']
        photo = request.files['photo']
        photo_bytes = photo.read()
        model=Schema()
        usersmodel=UsersModel()
        data = {'username':f"{username}",'firstname':f"{firstname}",\
            'lastname':f"{lastname}",'telephone':f"{telephone}",\
            'message':f"{message}"}
        photo_data = {'username':f"{username}",\
            'photo':photo_bytes,\
            'photo_name':f"{photo.filename}"}
        usersmodel.upsert(data)
        usersmodel.upsert_photo(photo_data)
        return render_template('users.html')
    else:
        return render_template('users.html')

@app.route("/get_users",methods=['GET'])
def get_users():
    if request.method == 'GET':
        usersmodel=UsersModel()
        users = usersmodel.list_items("1=1")
        return users

@app.route("/get_image",methods=['GET'])
def get_image():
    if request.method == 'GET':
        username = request.args.get('username')
        usersmodel=UsersModel()
        imagedb = usersmodel.get_image(username)
        return send_file(io.BytesIO(imagedb[0]),mimetype='image/png', \
            attachment_filename=imagedb[1])

if __name__ == "__main__":
    Schema()
    app.run(debug=True, port=8888)

Следващите стъпки, можете да използвате това github репо, за да тествате приложението си.

Надявам се да го намерите полезен, Приятно кодиране!!


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. убийте зомбита мъртви регионални сървъри

  2. Какво е InputSplit в Hadoop MapReduce?

  3. Какво е работа само за карта в Hadoop?

  4. Какво е автоматичен отказ при отказ в NameNode в Hadoop HDFS?

  5. Двигатели за обработка на големи данни – Коя да използвам?:Част 1