Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Refatorar código para usar o pymysql

Só consegui utilizar o arquivo prepara_banco.py usando o pymysql, no entanto não consigo criar o db na jogoteca. O mais próximo que consegui fazer o código rodar, foi com esta configuração,

from flask import Flask, render_template, request, redirect, session, flash, url_for
from models import Jogo, Imagem, Usuario
from dao import JogoDao
import pymysql
pymysql.install_as_MySQLdb()

app = Flask(__name__)
app.secret_key = 'alura'


db = pymysql.connect(user='root', passwd='admin', host='127.0.0.1', port=3306, database="jogoteca")
jogo_dao = JogoDao(db)

No entanto, o DAO disponibilizado pelo curso não conversa com esta configuração. O que posso fazer? Não consegui de nenhuma maneira instalar o flask_MySQLdb.

7 respostas

Oi Clarisse, tudo bem?

Perdão pela demora em lhe retornar. Sugiro que tente mais uma vez instalar o flask_MySQLdb, pois, caso use o pymysql, poderá ocorrer mudanças de sintaxe ao longo do curso. Qual erro ocorre quando você tenta instalar o flask_MySQLdb? E qual sistema operacional você utiliza?

Nádia,

eu uso Windows 10. O maior problema que tenho aqui é que por respostas anteriores eu não consegui usar o mysqlclient usando o Python 3.7.4. Tentei novamente e teoricamente consegui baixar, e agora retorna o erro:

Traceback (most recent call last):
  File "C:/Users/Pantufa/cursos/FlaskP300/jogoteca2/prepara_banco.py", line 31, in <module>
    conn.cursor().execute(criar_tabelas)
  File "C:\Users\Pantufa\AppData\Local\Programs\Python\Python37-32\lib\site-packages\MySQLdb\cursors.py", line 208, in execute
    assert isinstance(query, (bytes, bytearray))
AssertionError

segue o código do prepara_banco.py

import MySQLdb
print('Conectando...')
conn = MySQLdb.connect(user='root', passwd='admin', host='127.0.0.1', port=3306)

# Descomente se quiser desfazer o banco...
#conn.cursor().execute("DROP DATABASE `jogoteca`;")
#conn.commit()

criar_tabelas =  [
    "SET NAMES utf8mb4",
    "CREATE DATABASE jogoteca DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci",
    "USE jogoteca",
    """CREATE TABLE jogo (
      id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
      nome varchar(50) NOT NULL,
      categoria varchar(40) NOT NULL,
      console varchar(20) NOT NULL,
      PRIMARY KEy(id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
    """,
    """CREATE TABLE usuario (
      id varchar(8) NOT NULL PRIMARY KEY,
      nome varchar(20) COLLATE NOT NULL,
      senha varchar(8) COLLATE NOT NULL

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
    """
]

assert isinstance(conn.cursor().execute, object)
conn.cursor().execute(criar_tabelas)

# inserindo usuarios
cursor = conn.cursor()
cursor.executemany(
      'INSERT INTO jogoteca.usuario (id, nome, senha) VALUES (%s, %s, %s)',
      [
            ('luan', 'Luan Marques', 'flask'),
            ('nico', 'Nico', '7a1'),
            ('danilo', 'Danilo', 'vegas')
      ])

cursor.execute('select * from jogoteca.usuario')
print(' -------------  Usuários:  -------------')
for user in cursor.fetchall():
    print(user[1])

# inserindo jogos
cursor.executemany(
      'INSERT INTO jogoteca.jogo (nome, categoria, console) VALUES (%s, %s, %s)',
      [
            ('God of War 4', 'Ação', 'PS4'),
            ('NBA 2k18', 'Esporte', 'Xbox One'),
            ('Rayman Legends', 'Indie', 'PS4'),
            ('Super Mario RPG', 'RPG', 'SNES'),
            ('Super Mario Kart', 'Corrida', 'SNES'),
            ('Fire Emblem Echoes', 'Estratégia', '3DS'),
      ])

cursor.execute('select * from jogoteca.jogo')
print(' -------------  Jogos:  -------------')
for jogo in cursor.fetchall():
    print(jogo[1])

# commitando senão nada tem efeito
conn.commit()
cursor.close()

Clarisse, o mysqlclient é uma dependência do MySQLdb, e ele suporta até a versão 3.6 do Python.

Portanto, peço desinstale a versão do Python que utiliza atualmente e instale a versão 3.6, disponível neste link . Basta clicar no mesmo item marcado na imagem abaixo e executar o .exe:

Imagem2

Na instalação, lembre-se de marcar a opção para adicionar o Python ao path do windows.

Após os procedimentos acima, basta rodar o comando abaixo:

pip.exe install mysqlclient

Com isto, tente executar o prepara_banco.py disponibilizado na aula e modifique suas credenciais de acesso ao banco.

arquivo prepara_banco.py

Reforçando mais uma vez o motivo de eu te pedir para que tente instalar o MySQLdb novamente, é pelo fato de conseguirmos alinhar direitinho em relação a sintaxe que você está usando e o professor, desta forma, conseguirá obter maior aproveito do curso. Tudo bem?! Mas caso faça estes procedimentos ditos acima e ainda sim não consiga utilizar o MySQLdb, tentamos com o pymysql.

Abraços e bons estudos!

voltei o Python para a versão 3.6.7, e não continuo sem conseguir instalar o flask_mysqldb ou o mysqlclient

Command "c:\users\pantufa\appdata\local\programs\python\python36-32\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\Pantufa\\AppData\\Local\\Temp\\pip-install-yg3w51h1\\mysqlclient\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\Pantufa\AppData\Local\Temp\pip-record-l2upm2t_\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\Pantufa\AppData\Local\Temp\pip-install-yg3w51h1\mysqlclient\

e

Command "c:\users\pantufa\appdata\local\programs\python\python36-32\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\Pantufa\\AppData\\Local\\Temp\\pip-install-amdkjfba\\mysqlclient\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\Pantufa\AppData\Local\Temp\pip-record-afvr20ci\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\Pantufa\AppData\Local\Temp\pip-install-amdkjfba\mysqlclient\
solução!

Bom dia, Clarisse.

Como eu havia dito, caso tentássemos e não obtivéssemos sucesso no flask_mysqldb iríamos fazer a refatoração para o pymysql e aqui está.

Arquivo prepara_banco.py:

import pymysql

conn = pymysql.connect(host='localhost',
                       user='seu_user',
                       password='seu_password')

# Descomente se quiser desfazer o banco...
# conn.cursor().execute("DROP DATABASE `jogoteca`;")
# conn.commit()


# Criando o banco de dados
conn.cursor().execute('CREATE DATABASE IF NOT EXISTS jogoteca')

conn.select_db('jogoteca')

# Criando tabelas no banco
cur = conn.cursor()

cur.execute("CREATE TABLE `jogo` (`id` int NOT NULL AUTO_INCREMENT,`nome` varchar(50) NOT NULL,`categoria` varchar(40)  NOT NULL,`console` varchar(20) NOT NULL,PRIMARY KEY (`id`))")

cur.execute("CREATE TABLE `usuario` (`id` varchar(8) NOT NULL,`nome` varchar(20) NOT NULL,`senha` varchar(8) NOT NULL,PRIMARY KEY (`id`))")

# inserindo usuarios

cur.executemany(
      'INSERT INTO jogoteca.usuario (id, nome, senha) VALUES (%s, %s, %s)',
      [
            ('luan', 'Luan Marques', 'flask'),
            ('nico', 'Nico', '7a1'),
            ('danilo', 'Danilo', 'vegas')
      ])

cur.execute('select * from jogoteca.usuario')
print(' -------------  Usuários:  -------------')
for user in cur.fetchall():
    print(user[1])

# inserindo jogos
cur.executemany(
      'INSERT INTO jogoteca.jogo (nome, categoria, console) VALUES (%s, %s, %s)',
      [
            ('God of War 4', 'Ação', 'PS4'),
            ('NBA 2k18', 'Esporte', 'Xbox One'),
            ('Rayman Legends', 'Indie', 'PS4'),
            ('Super Mario RPG', 'RPG', 'SNES'),
            ('Super Mario Kart', 'Corrida', 'SNES'),
            ('Fire Emblem Echoes', 'Estratégia', '3DS'),
      ])

cur.execute('select * from jogoteca.jogo')
print(' -------------  Jogos:  -------------')
for jogo in cur.fetchall():
    print(jogo[1])

conn.commit()
cur.close()

Arquivo dao.py

from models import Jogo, Usuario

SQL_DELETA_JOGO = 'delete from jogo where id = %s'
SQL_JOGO_POR_ID = 'SELECT id, nome, categoria, console from jogo where id = %s'
SQL_USUARIO_POR_ID = 'SELECT id, nome, senha from usuario where id = %s'
SQL_ATUALIZA_JOGO = 'UPDATE jogo SET nome=%s, categoria=%s, console=%s where id = %s'
SQL_BUSCA_JOGOS = 'SELECT id, nome, categoria, console from jogo'
SQL_CRIA_JOGO = 'INSERT into jogo (nome, categoria, console) values (%s, %s, %s)'


class JogoDao:
    def __init__(self, db):
        self.__db = db

    def salvar(self, jogo):
        cursor = self.__db.cursor()

        if (jogo.id):
            cursor.execute(SQL_ATUALIZA_JOGO, (jogo.nome, jogo.categoria, jogo.console, jogo.id))
        else:
            cursor.execute(SQL_CRIA_JOGO, (jogo.nome, jogo.categoria, jogo.console))
            jogo.id = cursor.lastrowid
        self.__db.commit()
        return jogo

    def listar(self):
        cursor = self.__db.cursor()
        cursor.execute(SQL_BUSCA_JOGOS)
        jogos = traduz_jogos(cursor.fetchall())
        return jogos

    def busca_por_id(self, id):
        cursor = self.__db.cursor()
        cursor.execute(SQL_JOGO_POR_ID, (id,))
        tupla = cursor.fetchone()
        return Jogo(tupla[1], tupla[2], tupla[3], id=tupla[0])

    def deletar(self, id):
        self.__db.cursor().execute(SQL_DELETA_JOGO, (id, ))
        self.__db.commit()


class UsuarioDao:
    def __init__(self, db):
        self.__db = db

    def buscar_por_id(self, id):
        cursor = self.__db.cursor()
        cursor.execute(SQL_USUARIO_POR_ID, (id,))
        dados = cursor.fetchone()
        usuario = traduz_usuario(dados) if dados else None
        return usuario


def traduz_jogos(jogos):
    def cria_jogo_com_tupla(tupla):
        return Jogo(tupla[1], tupla[2], tupla[3], id=tupla[0])
    return list(map(cria_jogo_com_tupla, jogos))


def traduz_usuario(tupla):
    return Usuario(tupla[0], tupla[1], tupla[2])

No arquivo jogoteca.py inclua estes trechos:

import pymysql

db = pymysql.connect(host='localhost',
                       user='seu_user',
                       password='seu_password',
                       db='jogoteca')

Muito muito obrigada

De nada, Clarisse. Qualquer dúvida que houver durante o curso fique a vontade para postar aqui no fórum que iremos te ajudar.

Abraços e bons estudos!