Visão geral
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
Entendendo o MongoDB
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 |
Tutorial
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
Verifique os pré-requisitos
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:
Revise seu esquema de banco de dados SQL, incluindo tabelas, relacionamentos e tipos de dados.
Identifique queries e relacionamentos complexos que podem exigir cuidado especial no MongoDB.
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 .
Crie uma cópia de segurança completa do seu banco de dados SQL atual.
Atualizar os modelos de aplicação Spark
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 } 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çãoto_dict: Converte uma instância em um dicionário para armazenamento MongoDBfrom_dict: cria uma instânciaPosta partir de um dicionário__repr__: retorna uma representação de string da postagem
Atualize a configuração do aplicação Spark
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.
Atualizar as rotas do aplicação Pipeline
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 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) 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) 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) 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) 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")) 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
Postem dicionários usando o métodoto_dictpara armazenamento no MongoDBRecuperar 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
Exportar dados do SQLite
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.
Importar dados para o MongoDB
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.
Recursos adicionais
Para saber mais sobre o Mongo-Pymongo, consulte a documentação do Mongo-PyMongo.