Menu Docs
Página inicial do Docs
/ /

Tutorial: Migrar Frasco de SQL para MongoDB

Este tutorial mostra como migrar um aplicação Firefly de SQL para MongoDB . Especificamente, o tutorial converte um aplicação de blog de exemplo que usa SQLAlchemy em um que usaFlask-PyMongo.

O aplicação de exemplo inclui as seguintes funcionalidades:

  • Criação, edição e visualização de postagens de blog

  • Pesquisando blog posts

MongoDB é um banco de dados NoSQL que armazena dados em documentos. A lista a seguir descreve os principais conceitos do MongoDB :

  • Collections: Grupos de documentos, semelhantes a tabelas em bancos de dados SQL. As coleções não impõem um esquema.

  • Documentos: objetos semelhantes a JSON que armazenam dados. Os documentos podem conter arrays e subdocumentos aninhados.

  • BSON: formato JSON binário que o MongoDB usa internamente. O BSON estende o JSON com tipos de dados adicionais, como data e binário.

A tabela a seguir compara bancos de dados MongoDB e SQL:

funcionalidade
SQL
MongoDB

Esquema

Aplica um esquema fixo com tabelas e colunas predefinidas

Esquemas flexíveis que permitem modelos de dados dinâmicos

Estrutura de dados

Armazena dados em tabelas com linhas e colunas

Armazena dados em collections de documentos

Relacionamentos

Usa chaves estrangeiras e participações para estabelecer relações entre tabelas

Incorpora documentos dentro de outros documentos ou referência a eles, sem a necessidade de junções

Linguagem de query

Usa linguagem de query estruturada (SQL)

Usa uma linguagem de query rica baseada em JSON

Este tutorial mostra como concluir as seguintes etapas:

  • Verifique os pré-requisitos

  • Instalar o Flusk-PyMongo

  • Atualizar os modelos de aplicação Spark

  • Atualize a configuração do aplicação Spark

  • Atualizar as rotas do aplicação Pipeline

  • Exportar dados do SQLite

  • Importar dados para o MongoDB

  • Atualizar os modelos do Frasco

  • Executar o aplicação migrado

1

Este tutorial requer os seguintes pré-requisitos:

  • MongoDB instalado na sua máquina local. Consulte o guia Install MongoDB no manual do MongoDB Server para obter instruções.

  • Um aplicação Spark existente que usa SQLAlchemy. Você pode usar o exemplo de aplicação Spark do repositório flask-mongo no GitHub para este tutorial.

  • Python 3.7 ou posterior.

O aplicação de exemplo flask-mongo contém duas subpastas, flask-mongo e flask-sql. A pasta flask-sql contém um aplicação Spark que usa SQLAlchemy, que você pode usar para a migração neste tutorial.

Antes de iniciar a migração, conclua as seguintes ações:

  1. Revise seu esquema de banco de dados SQL, incluindo tabelas, relacionamentos e tipos de dados.

  2. Identifique queries e relacionamentos complexos que podem exigir cuidado especial no MongoDB.

  3. Crie seu esquema MongoDB considerando a natureza orientada a documentos do banco de dados. Para saber mais sobre o design de esquema no MongoDB, consulte o guia Designando seu esquema no manual do MongoDB Server .

  4. Crie uma cópia de segurança completa do seu banco de dados SQL atual.

2

Frask-PyMongo é uma extensão do MongoDB que integra o MongoDB com aplicativos do Mongo .

Instale o Flusk-PyMongo executando o seguinte comando:

pip install Flask-PyMongo Flask
3

Substitua o conteúdo do seu arquivo models.py pelo seguinte código:

from datetime import datetime
from bson.objectid import ObjectId
class Post:
def __init__(self, title, content, date_posted=None,
_id=None):
self.title = title
self.content = content
self.date_posted = date_posted if date_posted \
else datetime.utcnow()
self._id = _id if _id else ObjectId()
def to_dict(self):
return {
"title": self.title,
"content": self.content,
"date_posted": self.date_posted,
"_id": self._id
}
@staticmethod
def from_dict(data):
return Post(
title=data.get('title'),
content=data.get('content'),
date_posted=data.get('date_posted'),
_id=data.get('_id')
)
def __repr__(self):
return f"Post('{self.title}', \
'{self.date_posted}')"

Este código define uma classe Post que modela uma publicação de blog para o MongoDB. A classe inclui os seguintes métodos:

  • __init__: Define o título, conteúdo, data de publicação e identificador exclusivo para cada publicação

  • to_dict: Converte uma instância em um dicionário para armazenamento MongoDB

  • from_dict: cria uma instância Post a partir de um dicionário

  • __repr__: retorna uma representação de string da postagem

4

Substitua o conteúdo do seu arquivo __init__.py pelo seguinte código:

from flask import Flask
from flask_pymongo import PyMongo
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
mongo = PyMongo(app)
from app import routes

Este código inicializa o aplicação MongoDB para usar o MongoDB por meio da extensão MongoDB-PyMongo.

Atualize seu arquivo config.py para incluir as configurações do MongoDB adicionando o seguinte código:

import os
class Config:
SECRET_KEY = os.urandom(24)
MONGO_URI = 'mongodb://localhost:27017/blogdb'

Exclua o arquivo manage.py. Você usa esse arquivo para migrações de banco de dados no SQL, que não se aplica ao MongoDB.

Observação

Se você precisar de migrações para o MongoDB,oBeanie ODM fornecerá suporte de migração.

5

Substitua o conteúdo do seu arquivo routes.py pelo seguinte código:

from flask import render_template, url_for, flash, \
redirect, request
from app import app, mongo
from bson.objectid import ObjectId
from app.models import Post
from app.forms import PostForm
@app.route("/")
@app.route("/home")
def home():
posts_data = mongo.db.posts.find()
posts = [Post.from_dict(post) for post in posts_data]
return render_template("index.html", posts=posts)
@app.route("/post/new", methods=["GET", "POST"])
def new_post():
form = PostForm()
if form.validate_on_submit():
post = Post(title=form.title.data,
content=form.content.data)
mongo.db.posts.insert_one(post.to_dict())
flash("Your post has been created!", "success")
return redirect(url_for("home"))
return render_template("post.html", title="New Post",
form=form)
@app.route("/post/<post_id>")
def post(post_id):
post_data = mongo.db.posts.find_one_or_404(
{"_id": ObjectId(post_id)})
post = Post.from_dict(post_data)
return render_template("detail.html", post=post)
@app.route("/post/<post_id>/edit", methods=["GET", "POST"])
def edit_post(post_id):
post_data = mongo.db.posts.find_one_or_404(
{"_id": ObjectId(post_id)})
post = Post.from_dict(post_data)
form = PostForm()
if form.validate_on_submit():
updated_post = {
"$set": {"title": form.title.data,
"content": form.content.data}
}
mongo.db.posts.update_one(
{"_id": ObjectId(post_id)}, updated_post)
flash("Your post has been updated!", "success")
return redirect(url_for("post", post_id=post_id))
elif request.method == "GET":
form.title.data = post.title
form.content.data = post.content
return render_template("edit_post.html",
title="Edit Post", form=form)
@app.route("/post/<post_id>/delete", methods=["POST"])
def delete_post(post_id):
mongo.db.posts.delete_one({"_id": ObjectId(post_id)})
flash("Your post has been deleted!", "success")
return redirect(url_for("home"))
@app.route("/search", methods=["GET", "POST"])
def search():
query = request.args.get("query")
posts_data = mongo.db.posts.find(
{
"$or": [
{"title": {"$regex": query,
"$options": "i"}},
{"content": {"$regex": query,
"$options": "i"}},
]
}
)
posts = [Post.from_dict(post) for post in posts_data]
return render_template("index.html", posts=posts)

Este código atualiza as rotas para usar MongoDB em vez de SQLAlchemy. As rotas concluem as seguintes ações:

  • Converta instâncias Post em dicionários usando o método to_dict para armazenamento no MongoDB

  • Recuperar publicações usando mongo.db.posts.find()

  • Insira publicações usando mongo.db.posts.insert_one()

  • Atualizar publicações usando mongo.db.posts.update_one()

  • Excluir publicações usando mongo.db.posts.delete_one()

  • Pesquise publicações usando os recursos de regex do MongoDB

6

Crie um script Python denominado export_list_tables.py para listar todas as tabelas em seu banco de dados SQLite adicionando o seguinte código a um novo arquivo:

import sqlite3
# Connect to the SQLite database
db_path = 'relative/path/to/site.db'
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Query to get all table names
cursor.execute("SELECT name FROM sqlite_master WHERE \
type='table';")
tables = cursor.fetchall()
# Close the connection
conn.close()
print(tables)

Execute este script para exibir os nomes da sua tabela. O resultado mostra a tabela post.

Crie outro script Python denominado export_to_json.py para exportar os dados para JSON adicionando o seguinte código a um novo arquivo:

import sqlite3
import json
# Connect to the SQLite database
db_path = 'relative/path/to/site.db'
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Export data from the 'post' table
cursor.execute("SELECT * FROM post")
rows = cursor.fetchall()
# Get the column names
column_names = [description[0] for description in \
cursor.description]
# Convert to list of dictionaries
data = [dict(zip(column_names, row)) for row in rows]
# Save to a JSON file
with open('post.json', 'w') as f:
json.dump(data, f, indent=4)
# Close the connection
conn.close()

Execute este script para criar o arquivo post.json no diretório atual. Este arquivo contém seus dados exportados no formato JSON.

7

Crie um script Python denominado import_to_mongo.py para importar o arquivo JSON para o MongoDB adicionando o seguinte código a um novo arquivo:

from pymongo import MongoClient
import json
from datetime import datetime
def import_json_to_mongo(db_name, collection_name,
json_path):
client = MongoClient("mongodb://localhost:27017/")
db = client[db_name]
def convert_date(data):
# Update 'date_posted' field to datetime object
for item in data:
if 'date_posted' in item:
item['date_posted'] = datetime.strptime(
item['date_posted'],
'%Y-%m-%d %H:%M:%S.%f')
return data
with open(json_path, 'r') as f:
data = json.load(f)
data = convert_date(data)
db[collection_name].insert_many(data)
client.close()
if __name__ == "__main__":
db_name = 'blogdb'
collection_name = 'posts'
json_path = 'flask-mongo/post.json'
import_json_to_mongo(db_name, collection_name,
json_path)

Execute este script para importar seus dados para MongoDB. O script converte o campo date_posted em um objeto de data/hora e insere todas as publicações na coleção MongoDB .

Observação

A string de conexão mongodb://localhost:27017/blogdb se conecta à sua instância do MongoDB no localhost na porta 27017. O MongoDB cria o banco de dados automaticamente quando você escreve dados pela primeira vez.

8

Atualize seus arquivos de modelo para usar o ID de documento MongoDB alterando todas as instâncias de post_id=post.id para post_id=post._id.

9

Execute o aplicação Pipeline com o seguinte comando:

python run.py

Você pode acessar seu aplicação navegando até http://127.0.0.1:5000/home em seu navegador da web.

Para saber mais sobre o Mongo-Pymongo, consulte a documentação do Mongo-PyMongo.

Voltar

Tutorial: Implante um aplicativo Flask nos Aplicativos de Contêiner do Azure

Nesta página