I have code which activates my local Postgres server if it is not currently on, but once this command is sent, then I am unable to re-run anything in my editor. VSCode simply tells me "Code is currently running!" and the Output indicates that it is waiting for the server to disconnect before actually completing the entire script.
I want to be able to connect to postgresql straight-away by using psycopg2 and avoiding having to handle starting / stopping the local server, just as I would be able to with the EnterpriseDB installer version of PostgreSQL. However, if I can start the server, query the database, and then go about my merry way, that would also solve my issue. I want to be able to work on this Python script and others without locking up VSCode.
My issue stems from having to find a work-around for installing PostgreSQL on Windows 10. The installer was leading to a false "COMSPEC" environment variable error, so I unpacked the binaries instead. Unfortunately, I think that there is some issue with the configuration, since I am not able to run a simple query like the one below, which means that Postgres doesn't automatically start when called with psycopg2 in Python :
import psycopg2
conn = psycopg2.connect(
user='postgres',
host='127.0.0.1',
port='5432',
database='postgres'
)
cursor = conn.cursor()
SQL = 'select * from dual'
records = cursor.fetchall()
for record in records:
print('dummy :', record[0],'\n')
cursor.close()
conn.close()
^^^ This will return the following error, which is fixed when I start the server with pg_ctl :
Traceback (most recent call last):
File "c:\Users\UserName\Desktop\Test.py", line 7, in <module>
database='postgres'
File "C:\Users\UserName\AppData\Local\Programs\Python\Python37\lib\site-packages\psycopg2\__init__.py", line 126, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: Connection refused (0x0000274D/10061)
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
I have manually gone into my command prompt and run these :
pg_ctl -D "C:\Program Files\pgsql\data" stop
pg_ctl -D "C:\Program Files\pgsql\data" start
Ideally, I would be able to have this handled automatically, i.e. I can run a script and not need to shut off the server in order to re-run. Ideally, the server could get started in a background process which is separate from the script's process.
import os
import psycopg2
import subprocess
pg_ctl = r'C:\Program Files\pgsql\bin\pg_ctl.exe'
data_dir = r'C:\Program Files\pgsql\data'
def server_status(exe,data):
exe=exe
data=data
if (os.path.isfile(exe)) and (os.path.isdir(data)) :
proc = subprocess.Popen([exe,'-D',data,'status'],stdout = subprocess.PIPE)
server_status = proc.communicate()[0].rstrip().decode("utf-8")
elif (os.path.isfile(exe)) and not (os.path.isdir(data)) :
server_status = f'PostgreSQL data does not exist here : \n {data}'
elif not (os.path.isfile(exe)) and (os.path.isdir(data)) :
server_status = f'PostgreSQL Executable "pg_ctl.exe" does not exist here : \n {os.path.dirname(exe)}'
else :
server_status = 'Input parameters cannot be executed.\nPlease check where "pg_ctl.exe" and the database reside'
return server_status
def server_on(exe,data):
exe=exe
data=data
if server_status(exe,data) == 'pg_ctl: no server running':
try:
subprocess.check_call([exe,'-D',data,'start'])
return 'server started'
except (subprocess.CalledProcessError) as ex:
return f'Failed to invoke psql: {ex}'
elif server_status(exe,data) == 'server started':
return 'server started already'
print(server_status(pg_ctl,data_dir))
server_on(pg_ctl,data_dir)
print(server_status(pg_ctl,data_dir))
If the server is off, I get : 'server started' returned as the server_status. Then I cannot run anything until I manually shutdown the server. "Code is currently running!" is what is returned (by VSCode) once I try to edit the code and re-run immediately afterwards.
Install PostgreSQL with Binaries :
Download PostgrSQL Binaries
Unzip the downloaded file in the location that you want to have as your base directory for PostgreSQL
Open your CMD prompt, navigate to your "bin" e.g. "C:\Program Files\pgsql\bin"
Initialize the database : initdb [option...] [ --pgdata | -D ] directory
E.g. : initdb.exe -D ../data --username=postgres --auth=trust
^^^ This will create the directory "data" in the same directory as "bin" then create a username "postgres". Note, no password specified here. Only the directory is a required argument
Start the server : pg_ctl [option...] [ --pgdata | -D ] directory
E.g. pg_ctl.exe start -D ../data
^^^ This will start the server with what was initialized in the "\data" directory
Connect to "postgres" now that the server is up : psql --username=postgres
Execute : ALTER USER postgres WITH PASSWORD "my_password"
Execute : CREATE EXTENSION adminpack;
Connect to a database : psql DBNAME USERNAME
Switch databases : \c DBNAME
Exit : \q
Show all active connections in the CMD prompt : netstat -nat
edit "postgresql.conf" file as needed (within your "\data" directory) --> E.g. "listen_addresses = 'localhost'" and "port = 5432"
Register PostgreSQL as a service : pg_ctl register [-D datadir] [-N servicename] [-U username] [-P password] [-S a[uto] | d[emand] ] [-e source] [-W] [-t seconds] [-s] [-o options]
Links :
PostgreSQL Documentation
PostgreSQL 11 initdb.exe
PostgreSQL 11 pg_ctl.exe
PostgreSQL 11 start the server
Install PostgreSQL Binaries (Windows 10)
Install PostgreSQL Binaries and Register It as a Service
Enable Remote PostgreSQL Connection
Configure PostgreSQL to Allow Remote Connection
Allow Remote Connections
Accept TCPIP Connections
Configure PostgreSQL to Accept Local Connections Only
PostgreSQL Management on Windows
Starting PostgreSQL in Windows w/o Install
StackOverflow :
unix_socket_directories
PostgreSQL Database Service
How to use PostgreSQL in multi thread python program
How to run PostgreSQL as a service in windows?
Register and run PostgreSQL as Windows Service
PostgreSQL pg_ctl Register Service Error under Windows
How can I configure PostgreSQL to start automatically in Windows?
PostgreSQL isn't Listening on Port 5432 in Windows
PostgreSQL initialization on Linux
Update :
I have tried to register PostgreSQL as a service, but I do not have admin privileges. I believe this is the root of my problem, since I only get the error "pg_ctl: could not open service manager" when I try to execute :
pg_ctl.exe register -N postgres -D "C:\Program Files\pgsql\data"
I would either need to disable to firewall or have a batch file kick-off a command to start the PostgreSQL server on a separate thread to my Python scripts. Or I could just switch to Linux and literally none of this would be an issue :D
Related
I am using -in Linux- python 3 and psycopg2 to connect to some postres databases:
import psycopg2 as pg
connection = None
try:
connection = pg.connect(
user = "username",
password = "...",
host = "host_ip",
port = "5432",
database = "db_name",
)
cursor = connection.cursor()
# Print PostgreSQL Connection properties
print ( connection.get_dsn_parameters(),"\n")
# Print PostgreSQL version
cursor.execute("SELECT version();")
record = cursor.fetchone()
print("You are connected to - ", record,"\n")
cursor.close()
connection.close()
print("PostgreSQL connection is closed")
except (Exception, pg.Error) as error :
print ("Error while connecting to PostgreSQL", error)
For one of the DBs this works, but for the other I am getting:
Error while connecting to PostgreSQL FATAL: no pg_hba.conf entry for host "XXX.XXX.XXX.XXX", user "YYYY", database "ZZZZ", SSL off
I have checked the web and stackoverflow, and there are a lot of similar questions,
e.g. Psycopg2 reporting pg_hba.conf error
However, I am not root on the machine where I used pip/anaconda, and there seems to be no
sql service or anything similar running:
$ sudo systemctl status postgres*
$ sudo systemctl status postgres
Unit postgres.service could not be found.
$ sudo systemctl status postgresql
Unit postgresql.service could not be found.
$ sudo systemctl status post*
So none of the answers seem to be relevant, because this question seems to be based on the
postgress service running, or on the existence of pg_hba.conf, either of which do not in my system. Though note that a sample is included in my envs/py3/share/ (where py3 the name of my environment):
$ locate pg_hba.conf
/home/nick/anaconda3/envs/py3/share/pg_hba.conf.sample
My question here aims to -apart to find a way to solve my immediate problem- understand what psycopg2 is / how it ends up using pg_hba.conf, seemingly used in a postgresql service that does not seem to exist in my system:
Does psycopg2 is/uses a driver? Why does it seem to include pg_hba.conf.sample and what is one supposed to do with it? where to place pg_hba.conf(???) it to make psycopg2 read it?
Notes / Info based on comments:
The DB is not locally hosted. It is running on a different server.
I am able to access that DB using DBeaver and my local Ubuntu python, but a container (same psycopg2 version is not), so I speculate it is not a DB server issue.
It seems pg_hba.conf is a file that should only be on the server? (If so, that actually is part of the answer I am looking for...)
The Problem
I'm getting started with MongoDB on Python, I have a Ubuntu machine in my local network and MongoDB is installed there. When I try to connect with database using Python from Mac it throughs me an error. I searched about it and found out there is a .service called mongod.service that needs to be started along with mongodb.service. But when I try to start the mongod.service the it says the .service doesn't even exist. I tried both with IP and mongodb url, nothing works.
Ubuntu Terminal
$ sudo service mongod start
$ Failed to start mongod.service: Unit mongod.service not found.
$ sudo systemctl start mongod
$ Failed to start mongod.service: Unit mongod.service not found.
DataBase Link (a)
mongodb://user:password#192.168.0.106/database
Python Script (a)
#!/usr/bin/env python3
from pymongo import MongoClient
client = MongoClient('mongodb://user:password#192.168.0.106/database')
db = client['database']
collection = db['collection']
json = dict(message='hello world', token=0)
collection.insert_one(json)
macOS Terminal (a)
pymongo.errors.ServerSelectionTimeoutError: 192.168.0.106:27017: [Errno 61] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 60e140982a43032aef0dd634, topology_type: Single, servers: [<ServerDescription ('192.168.0.106', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('192.168.0.106:27017: [Errno 61] Connection refused')>]>
DataBase Link (b)
mongodb+srv://user:password#cluster0.h9fmz.mongodb.net/database?retryWrites=true&w=majority
Python Script (b)
#!/usr/bin/env python3
from pymongo import MongoClient
client = MongoClient('mongodb+srv://user:password#cluster0.h9fmz.mongodb.net/database?retryWrites=true&w=majority')
db = client['database']
collection = db['collection']
json = dict(message='hello world', token=0)
collection.insert_one(json)
macOS Terminal (b)
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/pymongo/pool.py", line 1278, in _get_socket
sock_info = self.sockets.popleft()
IndexError: pop from an empty deque
During handling of the above exception, another exception occurred:
.....
.....
.....
pymongo.errors.OperationFailure: bad auth : Authentication failed., full error: {'ok': 0, 'errmsg': 'bad auth : Authentication failed.', 'code': 8000, 'codeName': 'AtlasError'}
Note That
I'm providing the correct username and password for the database.
I'm using a machine on my local network, which is not a live server.
I've also tried the following commands but they did not solve anything.
Ubuntu Terminal
$ mongod --auth --port 27017
$ mongod --port 27017
$ sudo rm /var/lib/mongodb/mongod.lock
$ sudo mongod --repair
For accessing mongodb from another machine in local network. You will need to check the following:
There is no firewall restriction in the server machine or client machine. In case there is a firewall, you will need to add rule exceptions to allow this port to be accessible. Both incoming and outgoing. (Ubuntu firewall)
You will have to add bindIp config to the mongodb config in server machine. Refer to docs here. You will need to add something like this:
net:
bindIp: 0.0.0.0
port: 27017
Make sure you are able to connect using this ip: 192.168.0.106(server in local network) from the server machine itself. This will make sure the server is listening in this ip.
$ Failed to start mongod.service: Unit mongod.service not found.
The solution for this error could be found here
The mongo atlas error might be due to the following reasons:
You will have to create an database user in order to connect to mongodb.
you can find it under the left panel -> Database access -> Add user
This will be because of a mismatch with username and password. In case you have any special characters in your password you will have to url encode them.
I am using mysql-connector, when ever I run the container using docker I get this error:
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'db:3306' (-5 No address associated with hostname)
but when I run the project using python only it executes with no errors
I want to use phpmyadmin only for the database please help.
To create a docker from your linux machine:
docker pull mysql:latest
To run it and mount a persistent folder with port access on 3306 (std port for mysql):
docker run --name=mysql_dockerdb --env="MYSQL_ROOT_PASSWORD=<your_password>" -p 3306:3306 -v /home/ubuntu/sql_db/<your_dbasename>:/var/lib/mysql -d mysql:latest
To connect to the docker instance so that you can create the database within the docker:
docker exec -it mysql_dockerdb mysql -uroot -p<your_password>
My SQL code to establish the database:
CREATE DATABASE dockerdb;
CREATE USER 'newuser'#'%' IDENTIFIED BY 'newpassword';
GRANT ALL PRIVILEGES ON dockerdb.* to 'newuser'#'%';
ALTER USER 'username'#'%' IDENTIFIED WITH mysql_native_password BY 'userpassword';
You will now have a docker running with a persistent SQL database. You connect to it from your Python code. I am running Flask mySql. You will want to keep your passwords in environment variables. I am using a Mac so therefore my ~/.bash_profile contains:
export RDS_LOGIN="mysql+pymysql://<username>:<userpassword>#<dockerhost_ip>/dockerdb"
Within Python:
import os
SQLALCHEMY_DATABASE_URI = os.environ.get('RDS_LOGIN')
And at that point you should be able to connect in your usual Python manner. Note that I've glossed over any security aspects on the presumption this is local behind a firewall.
I am using windows8, for writing code I use IDLE. I tried to connect python to mongodb. But when trying to get collection name than it gives an error.
ServerSelectionTimeoutError: localhost:20101: [Errno 10061] No connection could be made because the target machine actively refused it
This is code for which i am getting an error.
from pymongo import MongoClient
connection = MongoClient('localhost',20101)
db = connection['Bhautik']
collection = db['Student']
db.collection_names(include_system_collections=True)
By the output message you probably didn't set your mongo bind_ip or didn't set the dbpath. Try this:
mongod --dbpath <database_path> --bind_ip 127.0.0.1 --port 20101
It would be more helpful to put alongside with your code some information regarding the mongodb configuration, like the server port, if you are using authentication or not, which dbpath you are using and so on.
So put in your question your mongodb.conf (if you are using one) or the command you are using to start the mongo server.
If you are starting to use mongoDB after installation, make C:/data/db because it is a default database directory which mongoDB uses.
To change the database directory, do type below:
C:\Program Files\MongoDB\Server\3.x\bin> mongod --dbpath "c:\custom_folder"
You can try
run mongo like that:
"C:\\Program Files\\MongoDB\\Server\\3.6\\bin\\mongod.exe" --dbpath E:\\data\\db --port 27017 --bind_ip 127.0.0.1
E:\data\db should be your location path
then in you code
it will lok like
client = MongoClient("127.0.0.1", 27017)
db = client['addsome']
datas = db.follow_up
and if you want to access from a distant machine make sure you open the port "27017" in the firewall
Some times it's gives this error when you forgot to run the local server (if it's run with local server).
To run it you need to write on your terminal:
mongod
or, if MongoDB not in PATH, you can find it via this link in your computer:
C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe
In order to run MongoDB,
You should have installed MongoDB into your OS, download it from https://www.mongodb.com/download-center/community?tck=docs_server
Add the installation's bin folder to your system environment variables.
Openup the terminal and check 'mongod' and 'mongo' commands are working.
Then try to rerun your python script.
I can not use .pgpass file while connecting to postgresql db using python script(((
My python script to connect is without password:
conn = psycopg2.connect("dbname='postgres' user='postgres' host='192.168.136.129'");
My .pgpass:
*:*:*:postgres:password
is located in /var/lib/postgresql - home directory for postgres user.
However when I connect to db locally:
psql -U postgres
no password is asked. But for python error is raised:
root#debian:/python_codes/Junior/Level1/DB1/Generator_py# python connect_db.py
Unable to connect to db...
Traceback (most recent call last):
File "connect_db.py", line 34, in connectdb
conn = psycopg2.connect("dbname='postgres' user='postgres' host='192.168.136.129'");
File "/usr/lib/python2.7/dist-packages/psycopg2/__init__.py", line 179, in connect
connection_factory=connection_factory, async=async)
OperationalError: fe_sendauth: no password supplied
Based on the prompt from this output:
root#debian:/python_codes/Junior/Level1/DB1/Generator_py# python
connect_db.py
you're running the commmand as Unix user root, so the corresponding .pgpass file must be located in root's HOME directory, which means not /var/lib/postgresql but probably /root or /
Also its permissions must be restricted to readable by the owner, that is, chmod 600 $HOME/.pgpass
To prevent user from launching pg_dump with a permanent .pgpass or use PGPASSWORD in command, one could create .pgpass just before pg_dump starts and delete it off 3 seconds later (inside a compiled program).
subprocess.Popen(echo 'hostname:port:database:username:password' > /home/user/.pgpass, shell=True).wait()
subprocess.Popen(echo 'sleep 3; rm /home/user/.pgpass; rm /home/user/remove-pgpass.sh' > /home/user/remove-pgpass.sh, shell=True).wait()
subprocess.Popen(chmod 600 /home/user/.pgpass, shell=True).wait()
subprocess.Popen(chmod +x /home/user/remove-pgpass.sh, shell=True).wait()
subprocess.Popen(/home/user/remove-pgpass.sh, shell=True)
subprocess.Popen(pg_dump -h localhost -d user-db -U db-admin > mydbdump.sql, shell=True).wait()