HBase
 sql >> Teknologi Basis Data >  >> NoSQL >> HBase

Membangun aplikasi web CRUD Sederhana dan penyimpanan gambar menggunakan Cloudera Operational Database dan Flask

Cloudera Operational Database (COD) adalah solusi dbPaaS terkelola yang tersedia sebagai pengalaman di Cloudera Data Platform (CDP). Ini menawarkan akses klien multi-modal dengan nilai kunci NoSQL menggunakan API Apache HBase dan SQL relasional dengan JDBC (melalui Apache Phoenix). Yang terakhir membuat COD dapat diakses oleh pengembang yang terbiasa membangun aplikasi yang menggunakan MySQL, Postgres, dll. Manfaat utama COD meliputi:

  • Penskalaan otomatis –  berdasarkan penggunaan beban kerja cluster dan akan segera memiliki kemampuan untuk meningkatkan/menurunkan skala cluster
  • Setel otomatis – kinerja yang lebih baik dalam jejak infrastruktur yang ada.
  • Sembuhkan otomatis – selesaikan masalah operasional secara otomatis (segera hadir).

Di blog ini, saya akan mendemonstrasikan bagaimana COD dapat dengan mudah digunakan sebagai sistem backend untuk menyimpan data dan gambar untuk aplikasi web sederhana. Untuk membangun aplikasi ini, kita akan menggunakan Phoenix, salah satu komponen dasar COD, bersama dengan Flask. Untuk menyimpan gambar, kami akan menggunakan kemampuan HBase (penyimpanan backend Apache Phoenix) yang disebut MOB (objek sedang). MOB memungkinkan kita untuk membaca/menulis nilai dari 100k-10MB dengan cepat.

*Untuk kemudahan penggunaan pengembangan, Anda juga dapat menggunakan server kueri Phoenix alih-alih COD. Server kueri adalah build kecil phoenix yang dimaksudkan untuk tujuan pengembangan saja, dan data dihapus di setiap build.

Semua kode ada di repo github saya.

Petunjuk:

1. Masuk ke Cloudera Management Console dan pilih pengalaman Database Operasional

2. Pilih lingkungan Anda dan beri nama DB Anda

3. Setelah DB habis, ambil URL dari thin JDBC client

4. Setel kata sandi beban kerja CDP Anda

5. Proyek kloning git repo dan persyaratan pemasangan:$ pip install -r requirements.txt

6. Buka folder aplikasi dan jalankan “setup.py” – ini akan membuat tabel dengan 3 record pengguna dan gambar mereka $ python setup.py

7. Jalankan server web flask untuk memulai aplikasi web:$ FLASK_APP=app.py python -m flask run –port=8888 –host=127.0.0.1  –reload –with-threads –debugger

8. Buka http://localhost:8888/users di browser Anda. Anda harus dapat melihat aplikasi berjalan! Sesederhana itu.

Menelusuri Kode

1. Kelas Skema,  Pada dasarnya menyimpan detail koneksi serta membuat dan melepaskan metode tabel. Seperti yang Anda lihat, kolom "foto" adalah jenis VARBINARY, yang diterjemahkan ke objek MOB di 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 Kelas pengguna bertanggung jawab atas semua operasi aplikasi dengan Phoenix. Kami dapat memperbarui/menyisipkan (memasukkan dalam bahasa phoenix), menghapus, membuat daftar, dan menangani transaksi gambar:

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 adalah router utama untuk aplikasi. Ini berisi semua penanganan dengan input pengguna dan mengarahkannya ke metode koneksi. Saya memisahkan penanganan gambar untuk kemudahan penggunaan, dan dengan cara itu saya bisa mendapatkan gambar tertentu untuk pengguna:

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)

Langkah selanjutnya, Anda dapat menggunakan repo github ini untuk menguji aplikasi Anda.

Semoga bermanfaat, Selamat coding!!


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. How-to:Gunakan Antarmuka Apache HBase REST, Bagian 3

  2. Pengantar Lokalitas Data di Hadoop MapReduce

  3. Blok Data HDFS – Pelajari Internal Hadoop Data Besar

  4. Pengindeksan Email Menggunakan Cloudera Search dan HBase

  5. Apa itu NameNode Automatic Failover di Hadoop HDFS?