Error while connecting to mysql database, haskell - mysql

I'm absolutely newbie to haskell, but I need to write a simple application to work with DB. I'm reading realworldhaskell book, chapter about using databases: http://book.realworldhaskell.org/read/using-databases.html.
I've installed HDBC and HDBC-mysql and trying to run:
ghci> :module Database.HDBC Database.HDBC.MySQL
but receive error
attempting to use module ‘Database.HDBC.MySQL’ (./Database/HDBC/MySQL.hs) which is not loaded.
Does someone have some idea how to fix it and by what is is caused? Thanks!

I could solve the problem installing mysql on MacOS,
brew install mysql
mysql.server start ## mysqld
Followed by
cabal install HDBC
cabal install HDBC-mysql
Then could I create MySQL connection,
import Control.Monad
import Database.HDBC
import Database.HDBC.MySQL
main = do conn <- connectMySQL MySQLConnectInfo {
mysqlHost = "localhost",
mysqlUser = "root",
mysqlPassword = "",
mysqlDatabase = "chat_server",
mysqlPort = 3306,
mysqlUnixSocket = "/tmp/mysql.sock",
mysqlGroup = Just "test"
}
rows <- quickQuery' conn "SELECT 1 + 1" []
forM_ rows $ \row -> putStrLn $ show row
Note: you might need to update mysqlUnixSocket based on where is it located which can be found with following command:
sudo find / -type s

Related

How to create a mysql database in Django on the first run?

I'd like my application to be "plug-and-play", so I need to automatically create the database on the first run. I use docker with docker-compose
My attempt is to connect without specifying the database name and run a custom command before running the server:
command:
sh -c "python manage.py create_db &&
python manage.py runserver 0.0.0.0:8000"
And the command itself:
class Command(BaseCommand):
"""Django command to create DB"""
def handle(self, *args, **options):
con = connections['default']
db_name = os.environ.get('DB_NAME')
db_up = False
while not db_up:
try:
cursor = con.cursor()
cursor.execute(f'CREATE DATABASE IF NOT EXISTS {db_name}')
cursor.execute(f'USE {db_name}')
db_up = True
except Exception as err:
self.stdout.write('Database unavailable, waiting 1 second...')
self.stdout.write(str(err))
time.sleep(1)
self.stdout.write(self.style.SUCCESS('Database available!'))
If this is the right way, then now I just need to update the connection to use the newly created database, but I don't know how. The line cursor.execute(f'USE {db_name}') of course doesn't work.
Is it the right way to create the database?
If so, how to update the connection?
If not, how to do it?
Thanks!
EDIT
After hints from Nealium, I created an independent script (not a Django command) which I run before running the server.
import os
import time
from MySQLdb import _mysql
import os
db_host=os.environ.get('DB_HOST')
db_user=os.environ.get('DB_USER')
db_password=os.environ.get('DB_PASS')
db_name = os.environ.get('DB_NAME')
db_up = False
while not db_up:
try:
db = _mysql.connect(
host=db_host,
user=db_user,
password=db_password
)
db_up = True
db.query(f'CREATE DATABASE IF NOT EXISTS {db_name}')
db.close()
except Exception as err:
print('Database unavailable, waiting 1 second...')
time.sleep(1)
print('Database available!')
This what my management command generally looks like
call_command() basically does python manage.py {command}
Updated dothing command
from django.core.management.base import BaseCommand
from django.core.management import call_command
def create_db():
import mysql.connector
try:
mydb = mysql.connector.connect(
host=os.environ.get('DB_HOST'),
user=os.environ.get('DB_USER'),
password=os.environ.get('DB_PASS')
)
mycursor = mydb.cursor()
mycursor.execute('CREATE DATABASE IF NOT EXISTS {0}'.format(os.environ.get('DB_NAME')))
return True
except mysql.connector.Error as err:
print('Something went wrong: {}'.format(err))
except Exception as ex:
message("Exception: {}".format(ex))
return False
class Command(BaseCommand):
help = 'does thing'
def add_arguments(self, parser):
# Named (optional) arguments
parser.add_argument(
'--import',
action='store_true',
help='Skips Import',
)
def handle(self, *args, **kwargs):
print("Doing Thing")
# connect to db + create if it doesn't exist
status = create_db()
if status:
# create migrations
call_command('makemigrations') # (Django Command)
# can also pass arguemnts like a specific app
# call_command('makemigrations', 'app1')
# This create db **if** it doesn't exist
# + checks that migrations are up to date
call_command('migrate') # (Django Command)
if kwargs['import']:
# another management command to handle importing
# I've just a csv reader and a loop
call_command('importDb') # (Custom Command)
# Collect Static (+ don't ask for confirmation)
call_command('collectstatic', interactive=False) # (Django Command)
print('Thing has been Done')
else:
print('Thing not Done')
So with that, I just run:
python manage.py dothing (python manage.py dothing --import if I want db to be imported)
and then:
python manage.py runserver and it's good to go!
Edit
Just do something like this and pull the options from the settings:
https://www.w3schools.com/python/python_mysql_create_db.asp
Edit 2
It should work; From my testing Django doesn't actually connect to the db until its told to run a query (filter/get/create/delete)
You can generally test this with a basic management command and bad db settings:
Set db name in settings to 'invalid_db'
Test command below
from django.core.management.base import BaseCommand
from django.core.management import call_command
import os
class Command(BaseCommand):
help = 'testing '
def handle(self, *args, **kwargs):
print('Command is Running!')
print('doing the things')
print('about to migrate / use db / crash')
print('*'*100)
call_command('migrate')
So in theory, as long as you aren't using Django commands you should be able to do whatever you want

Failing to connect to MySQL in Dlang with vibe-d and mysql-native

I have simple vibe-D program which is trying to connect to SQL:
import std.stdio;
import mysql;
import vibe.d;
void main()
{
MySQLPool db_pool = new MySQLPool("localhost","root","","dbname",3306);
Connection db = db_pool.lockConnection();
// same thing happens with:
// string connectionStr = "host=localhost;port=3306;user=root;db=dbname";
// db = new Connection(connectionStr);
}
(I deleted everything else for simplification)
Dependencies:
"dependencies": {
"mysql-native": "~>3.2.0",
"vibe-d": "~>0.9.4"
}
And it fails to connect with:
object.Exception#../../../.dub/packages/vibe-core-1.22.4/vibe-core/source/vibe/core/net.d(256): Failed to connect to [0:0:0:0:0:0:0:1]:3306: refused
When I try it without vibe-d in the dub project (using phobos sockets) it connects with no problem. What am I doing wrong?
that's an ipv6 address.... is your mysql listening on that interface? might help trying 127.0.0.1 instead of localhost and seeing what happens.
can also consider reconfiguring mysql to listen on all interfaces too, including the ipv6

ModuleNotFoundError: No module named 'mysql.connector'; 'mysql' is not a package v2021

I'm trying a simple database connection.
"""
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='options',
user='root',
password='xxxxx')
if connection.is_connected():
db_Info = connection.get_server_info()
print("Connected to MySQL Server version ", db_Info)
cursor = connection.cursor()
cursor.execute("select database();")
record = cursor.fetchone()
print("You're connected to database: ", record)
except Error as e:
print("Error while connecting to MySQL", e)
finally:
if connection.is_connected():
cursor.close()
connection.close()
print("MySQL connection is closed")
"""
This works - once - if I uninstall and reinstall MySQL. When I try it a second time if fails to the above Traceback. When it works I've tried a simple read of some of the data. This also works only once per reinstall.
"""
import mysql.connector
try:
connection = mysql.connector.connect(host='localhost',
database='options',
user='root',
password=xxxxxx)
sql_select_Query = "SELECT command” (my SELECT command is lengthy so I’ve omitted it)
cursor = connection.cursor()
cursor.execute(sql_select_Query)
# get all records
records = cursor.fetchall()
print("Total number of rows in table: ", cursor.rowcount)
print("\nPrinting each row")
for row in records:
print("col1 = ", row[0], )
print("col2 = ", row[1])
print("col3 = ", row[2])
print("col4= ", row[3], "\n")
except mysql.connector.Error as e:
print("Error reading data from MySQL table", e)
finally:
if connection.is_connected():
connection.close()
cursor.close()
print("MySQL connection is closed")
"""
I've done the MySQL installation of the server, workbench, and connector (3x).
I'm using Windows 10 Home with the latest Anaconda release.
Python 3.8.11 (default, Aug 6 2021, 09:57:55) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
I’ve uninstalled ALL mysql entries in the pip list and reinstalled them (multiple times).
I have no issues accessing the database from MySQL Workbench.
(base) PS C:\Users\WARNE> pip list
Package Version
mysql 0.0.3
mysql-connector-python 8.0.26
mysqlclient 2.0.3
(base) PS C:\Users\WARNE> conda install -c anaconda mysql-connector-python
Collecting package metadata (current_repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
…this continued to fail
I've tried about every solution in all of the related questions without any luck. Any help/suggestions would be appreciated.
I finally went back to basics and re-installed, went to very simple code, etc. and this started working. This seems to be a weakness in python-MySQL interworking. This was frustrating.

How to change the authentication configuration of mysql connector to python?

I was trying to connect MySQL with python via the following code.
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="qwerty",
auth_plugin="mysql_native_password"
)
print(mydb)
It gave me the following error:-
mysql.connector.errors.NotSupportedError: Authentication plugin 'caching_sha2_password' is not supported
My connector version is:-
C:\Users\samar>pip install mysql-connector-python
Requirement already satisfied: mysql-connector-python in c:\users\samar\anaconda3\lib\site-packages (8.0.21)
import pymysql
host="localhost"
user="root"
passwd="qwerty"
db="<give db name"
def dbConnectivity(host,user, passwd, db):
try:
db = pymysql.connect(host=host,
user=user,
passwd=passwd,
db=db)
cursor = db.cursor()
print("Great !!! Connected to MySQL Db")
return cursor
except pymysql.Error as e:
print("Sorry !! The error in connecting is:" + str(e))
return str(e)
dbConnectivity(host,user,passwd,db)

Reading laravel .env values in windows terminal and use them as credentials for mysql in a batch file

I created a .bat script to import several .csv in my DB for a Laravel project.
At first, I was using python and each time it took an eternity to restore long files, so I decided to back up those tables and restore them with MySQL.
old .bat file
echo.
echo - Rebuilding database
php artisan migrate:fresh
echo.
echo - Importing animals data
cd py_animalimporter
python importer.py
cd ..
echo.
echo - Importing colors data
cd py_colorimporter
python importer.py
cd ..
echo.
echo - Rebuilding database
php artisan db: seed
echo.
echo - Importing places data
cd py_placeimporter
python importer.py
cd ..
echo.
echo - Starting local server
php artisan serve
New .bat file
echo.
echo - Rebuilding database
php artisan migrate:fresh
echo.
echo - Restoring sql backup
mysql -u username -p test_local < backup.sql
password
echo.
echo - Rebuilding database
php artisan db: seed
echo.
echo - Importing places data
cd py_placeimporter
python importer.py
cd ..
echo.
echo - Starting local server
php artisan serve
My python scripts read MySQL credentials from my laravel.env file (thanks to dotenv library), unfortunately, I can't figure how to do anything similar from the windows terminal.
.env file
DB_HOST=127.0.0.1
DB_PORT=3308
DB_DATABASE=test_local
DB_USERNAME=username
DB_PASSWORD=password
.py files example
from dotenv import load_dotenv
from pathlib import Path
import os
import mysql.connector
from mysql.connector import errorcode
def connectDb():
# Retrieve db credentials from .env
env_path = '../.env'
load_dotenv(dotenv_path=env_path)
db_host = os.getenv("DB_HOST")
db_port = os.getenv("DB_PORT")
db_database = os.getenv("DB_DATABASE")
db_username = os.getenv("DB_USERNAME")
db_password = os.getenv("DB_PASSWORD")
if db_password is None:
db_password = ''
return mysql.connector.connect(user=db_username, password=db_password,
host=db_host,
port=db_port,
database=db_database)
def insertPrimaryColour(hex,color):
try:
cnx = connectDb()
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("] Wrong Credentials")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("] No Existing Database")
else:
print("] " + err)
else:
cursor = cnx.cursor()
query = f"INSERT INTO dom_colors(`order`,hex,id_translation) VALUES(0,'{hex}','{color}');"
cursor.execute(query)
insert_id = cursor.lastrowid
cnx.commit()
cnx.close()
return insert_id
Alternately, I could use python to restore the DB but everything I tried didn't work!
If you want to make ad os indipendent solution you can try to use subprocess.
You can use in this way:
mysqlLogin = [...]
process = subprocess.Popen(mysqlLogin, shell=True, stdout=subprocess.PIPE)
process.wait()
This code line will run the command contained in mysqlLogin and wait for his termination.
You can also configure standard output redirection with stdout paramters.
Here is the docs: https://docs.python.org/3/library/subprocess.html
I finally found a solution with Python sending code to the Windows Terminal!
Here's the Python Script that now I call from the batch file
from dotenv import load_dotenv
from pathlib import Path
import os
def restoreDB():
# Retrieve DB credentials from .env
env_path = '.env'
load_dotenv(dotenv_path=env_path)
#db_host = os.getenv("DB_HOST")
#db_port = os.getenv("DB_PORT")
db_database = os.getenv("DB_DATABASE")
db_username = os.getenv("DB_USERNAME")
db_password = os.getenv("DB_PASSWORD")
if db_password is "":
mysqlLogin = "mysql -u "+db_username+" "+db_database+" < backup.sql"
else:
mysqlLogin = "mysql -u "+db_username+" --password='"+db_password+"' "+db_database+" < backup.sql"
os.system('cmd /c "%s"' % mysqlLogin)
restoreDB()