duplicate key error collection: mydatabase.customers index: _id_ dup key - python

I want to check if the user exists. If user does exist, do not insert it.
This is my code:
#!/usr/bin/env python
# Python code to illustrate
# inserting data in MongoDB
from pymongo import MongoClient
try:
myclient = MongoClient('10.1.3.18',27017)
print("Connected successfully!!!")
except:
print("Could not connect to MongoDB")
# database
emp_rec1 = {
"name":"Mr.Geek1",
"eid":24,
"location":"delhi"
}
emp_rec2 = {
"name":"Mr.Shaurya",
"eid":14,
"location":"delhi"
}
emp_rec3 = {
"name":"Mr.Shaurya111",
"eid":141111,
"location":"delhi111111"
}
a=[emp_rec1,emp_rec2,emp_rec3]
mydb = myclient["mydatabase"]
#result = mydb.profiles.create_index([('user_id'],unique=True)
mycol = mydb["customers"]
#x = mycol.insert_one(a[2])
cursor = mycol.find()
for record in cursor:
print(record)
mydb.servers.getIndexes()
if record['name']!="Mr.Shaurya":
x = mycol.insert_one(a[0])
print(record)
Is this code correct? Or there is an other solution?
and if I run my code twice I get this error:
pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection:
mydatabase.customers index: _id_ dup key: { :ObjectId('5d7b9a6bc9a8569a44a6da2c') }
How to prevent duplicated key in MongoDB?
How can I use index?

Assuming that eid is your Primary Key column that is causing the Duplicate Key error, the code below should fix your problem.
When you loop through cursor, you want to also loop through you array a and see if the eid in a also exists in database cursor. If it does not exist, then record will be inserted using x = mycol.insert_one(a[0])
Code:
#!/usr/bin/env python
# Python code to illustrate
# inserting data in MongoDB
from pymongo import MongoClient
try:
myclient = MongoClient('10.1.3.18',27017)
print("Connected successfully!!!")
except:
print("Could not connect to MongoDB")
# database
emp_rec1 = {
"name":"Mr.Geek1",
"eid":24,
"location":"delhi"
}
emp_rec2 = {
"name":"Mr.Shaurya",
"eid":14,
"location":"delhi"
}
emp_rec3 = {
"name":"Mr.Shaurya111",
"eid":141111,
"location":"delhi111111"
}
a=[emp_rec1,emp_rec2,emp_rec3]
mydb = myclient["mydatabase"]
#result = mydb.profiles.create_index([('user_id'],unique=True)
mycol = mydb["customers"]
#x = mycol.insert_one(a[2])
cursor = mycol.find()
for record in cursor:
print(record)
mydb.servers.getIndexes()
for i in a:
if record['eid'] != i['eid']:
x = mycol.insert_one(a[0])
print(record)
If you want to strictly check only the name of user in customers table, you can use the following query.
Code:
#!/usr/bin/env python
# Python code to illustrate
# inserting data in MongoDB
from pymongo import MongoClient
try:
myclient = MongoClient('10.1.3.18',27017)
print("Connected successfully!!!")
except:
print("Could not connect to MongoDB")
# database
emp_rec1 = {
"name":"Mr.Geek1",
"eid":24,
"location":"delhi"
}
emp_rec2 = {
"name":"Mr.Shaurya",
"eid":14,
"location":"delhi"
}
emp_rec3 = {
"name":"Mr.Shaurya111",
"eid":141111,
"location":"delhi111111"
}
a=[emp_rec1,emp_rec2,emp_rec3]
mydb = myclient["mydatabase"]
#result = mydb.profiles.create_index([('user_id'],unique=True)
mycol = mydb["customers"]
#x = mycol.insert_one(a[2])
cursor = mycol.find()
for record in cursor:
print(record)
mydb.servers.getIndexes()
for i in a:
if record['name'] != i['name']:
x = mycol.insert_one(a[0])
print(record)

Related

Mock: What Is the right way to mock sqlalchemy database?

This is what I've done for testing database
#patch.object(query_functions, 'connection')
def test_service_reg_return_correct_data(self, mock_sqlalchmey):
data = {
"user_name": "testuser53",
"password": "123456",
"email_address": "testuser53#example.com",
"dob": "2022-06-07 00:00:00",
"address": "Ahmedabad",
}
# json_data = json.dumps(data)
# print("jsob", json_data)
m1 = mock.MagicMock()
m1.get_json.return_value = data
print("m", m1)
with mock.patch("backened.routes.register.request", m1):
response =user_register()
self.assertTrue(mock_sqlalchmey.called)
self.assertEqual(response.json, {'Message': 'New user Created'},201)
I've tested this function
def user_register():
request_data = request.get_json()
insert = service_register(request_data)
print(type(insert))
return insert
inside service_register(), I've run_insert() for execution of queries i.e query_functions.py file.
query_functions.py
def connection():
engine = create_engine('mysql://root:admin#172.17.0.2:3306/flask', poolclass = NullPool)
conn = engine.connect()
return conn
def run_insert(data):
conn = connection()
sql = text(CONST_INSERT)
print(sql)
conn.execute(sql, data)
conn.close()
return ("executed")
I want to know whether it is right or wrong as I was trying to mock my database and don't want to insert data into DB. I'm not sure how database mock happened in this.

MongoDB $geoIntersect query runs in Compass and Studio 3T, but not in Python - any ideas?

Here is the script which i have working inside MongoDBs Compass and working inside Studio 3T
db.getCollection("collection").find({
geometry: {
$geoIntersects: {
$geometry: {
type: "Polygon" ,
coordinates: [ [
[-2.4478329206542915, 52.679303638992494], [-2.4423397565917915, 52.677534343091544], [-2.445601322753901, 52.67430779548455], [-2.4509228254394477, 52.676129262942176], [-2.4478329206542915, 52.679303638992494]
] ]
}
}
}
})
and it returns the following results:
As you can see the code seems to work fine, but when I try to run this inside a Python script it keeps failing and I need a little help pointing out the seemingly not so obvious error.
I have changed the fin statement to a simple field find and it works, just not when its a geoIntersects find statement.
However, if I try to do this inside python I keep getting errors.
Please see below for a copy of my python script, sorry for the redacted comments but need to keep data secure.
import pymongo
#mongodb service vars
dbStartc = 'mongodb+srv://'
dbDomain = '#cluster0.o7cud.azure.mongodb.net'
dbUser = 'redacted'
dbPass = 'redacted'
dbName = 'redacted'
dbColl = 'redacted'
dbSettings = '/?retryWrites=true&w=majority'
#test vars
dbName_connected = False
dbColl_connected = False
try:
#conect to the mongodb instance
mongoURL = dbStartc + dbUser + ':' + dbPass + dbDomain + dbSettings
mongocon = pymongo.MongoClient(mongoURL)
#connect to the database
dblist = mongocon.list_database_names()
if dbName in dblist:
mongocdb = mongocon[dbName]
#print("MongoDB Service - Database connected")
dbName_connected = True
#connect to the collection we need
collist = mongocdb.list_collection_names()
if dbColl in collist:
mongocol = mongocdb[dbColl]
#print("MongoDB Service - Collection connected")
dbColl_connected = True
#pre checks test
if dbName_connected and dbColl_connected :
#print("MongoDB Service - Connection Checks Complete")
find_result = []
found_count = 0
found_count = mongocol.count_documents( )
if found_count > 0 :
print("Collection Document Count: " + found_count)
mydoc = mongocol.find({ geometry: { $geoIntersects: { $geometry: { type: "Polygon" , coordinates: [ [ [-2.44783, 52.67930], [-2.44233, 52.67753], [-2.44560, 52.67430], [-2.45092, 52.67612], [-2.44783, 52.67930] ] ] } } } })
#for x in
for x in mydoc:
find_result += [x]
print(find_result)
else :
print("MongoDB Service - Connection Checks Failed")
except Exception as ex:
print ("Something you were not expecting went wrong! (" + ex + ")")
Here is the error:
Any help in getting python to work would be greatly appreciated

How to update row in mongodp in python

I have a following problem. I am creating a a mongodb. Rows looks like this:
{'_id': ObjectId('62136674d12e4f7384caf6c0'), 'visit_id': 595002379, 'referal': '', 'pageviews': [], 'ab_variants': [{'id': 1, 'var': 0}]}.
I am inserting new rows. I want to check if visit_id already exists. If yes, I want to extend ab_variants for example like this:
{'_id': ObjectId('62136674d12e4f7384caf6c0'), 'visit_id': 595002379, 'referal': '', 'pageviews': [], 'ab_variants': [{'id': 1, 'var': 0}, {'id': 2, 'var': 1}]}.
What I tried co far:
from pymongo import MongoClient
try:
conn = MongoClient()
print("Connected successfully!!!")
except:
print("Could not connect to MongoDB")
# database
db = conn.database
# Created or Switched to collection names: my_gfg_collection
collection = db.my_gfg_collection
# drop
db.my_gfg_collection.drop()
print("Old data dropped successfully!")
if collection.find_one({"visit_id": 595002379}) is None:
emp_rec = {
"visit_id": 595002379),
"referal": "",
"pageviews": [],
"ab_variants": [{"id" : 1),
"var" : 0) }]
}
else:
# I WANT TO UPDATE HERE
# Insert Data
rec_id = collection.insert_one(emp_rec)
How can I do this, please?
You can do something like this here
from pymongo import MongoClient
try:
conn = MongoClient()
print("Connected successfully!!!")
except:
print("Could not connect to MongoDB")
# database
db = conn.database
# Created or Switched to collection names: my_gfg_collection
collection = db.my_gfg_collection
# drop
db.my_gfg_collection.drop()
print("Old data dropped successfully!")
# store the document in a variable, if present
record = collection.find_one({"visit_id": 595002379})
if record is None:
emp_rec = {
"visit_id": 595002379),
"referal": "",
"pageviews": [],
"ab_variants": [{"id" : 1),
"var" : 0) }]
}
# Insert Data
rec_id = collection.insert_one(emp_rec)
else:
# I WANT TO UPDATE HERE
if 'ab_variants' not in record:
record['ab_variants'] = []
record['ab_variants'].append(Record that you want to update inside the ab_variants list)
# update the document
collection.update({'_id': record['_id']}, {"$set": record}, upsert=True)

building json data from sql database cursor

Without knowing the structure of the json, how can I return a json object from the database query? All of the the information is there, I just can't figure out how to build the object.
import MySQLdb
import json
db = MySQLdb.connect( host, user, password, db)
cursor = db.cursor()
cursor.execute( query )
rows = cursor.fetchall()
field_names = [i[0] for i in cursor.description]
json_string = json.dumps( dict(rows) )
print field_names[0]
print field_names[1]
print json_string
db.close()
count
severity
{"321": "7.2", "1": "5.0", "5": "4.3", "7": "6.8", "1447": "9.3", "176": "10.0"}
The json object would look like:
{"data":[{"count":"321","severity":"7.2"},{"count":"1","severity":"5.0"},{"count":"5","severity":"4.3"},{"count":"7","severity":"6.8"},{"count":"1447","severity":"9.3"},{"count":"176","severity":"10.0"}]}
The problem you are encountering happens because you only turn the fetched items into dicts, without their description.
dict in python expects either another dict, or an iterable returning two-item tuples, where for each tuple the first item will be the key, and the second the value.
Since you only fetch two columns, you get the first one (count) as key, and the second (severity) as value for each fetched row.
What you want to do is also combine the descriptions, like so:
json_string = json.dumps([
{description: value for description, value in zip(field_names, row)}
for row in rows])
1- You can use pymsql DictCursor:
import pymysql
connection = pymysql.connect(db="test")
cursor = connection.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT ...")
row = cursor.fetchone()
print row["key"]
2- MySQLdb also includes DictCursor that you can use. You need to pass cursorclass=MySQLdb.cursors.DictCursor when making the connection.
import MySQLdb
import MySQLdb.cursors
connection = MySQLdb.connect(db="test",cursorclass=MySQLdb.cursors.DictCursor)
cursor = connection.cursor()
cursor.execute("SELECT ...")
row = cursor.fetchone()
print row["key"]
I got this to work using Collections library, although the code is confusing:
import MySQLdb
import json
import collections
db = MySQLdb.connect(host, user, passwd, db)
cursor = db.cursor()
cursor.execute( query )
rows = cursor.fetchall()
field_names = [i[0] for i in cursor.description]
objects_list = []
for row in rows:
d = collections.OrderedDict()
d[ field_names[0] ] = row[0]
d[ field_names[1] ] = row[1]
objects_list.append(d)
json_string = json.dumps( objects_list )
print json_string
db.close()
[{"count": 176, "severity": "10.0"}, {"count": 1447, "severity": "9.3"}, {"count": 321, "severity": "7.2"}, {"count": 7, "severity": "6.8"}, {"count": 1, "severity": "5.8"}, {"count": 1, "severity": "5.0"}, {"count": 5, "severity": "4.3"}]

Iterating rows with Pyodbc

I am using Pyodbc to return a number of rows which are dumped into a JSON and sent to a server. I would like to iterate my SQL table and return all records. I am using cursor.fetchall() now, and the program returns one record. As shown below. When I use fetchone an error is returned AttributeError: 'unicode' object has no attribute 'SRNUMBER' and fetchmany returns one record as well. How do I successfully return all records? I am using Python 2.6.7
Code:
import pyodbc
import json
import collections
import requests
connstr = 'DRIVER={SQL Server};SERVER=server;DATABASE=ServiceRequest; UID=SA;PWD=pwd'
conn = pyodbc.connect(connstr)
cursor = conn.cursor()
cursor.execute("""
SELECT SRNUMBER, FirstName, LastName, ParentNumber
FROM MYLA311 """)
rows = cursor.fetchone()
objects_list = []
for row in rows:
d = collections.OrderedDict()
d['SRNUMBER']= row.SRNUMBER
d['FirstName']= row.FirstName
d['LastName']= row.LastName
d['ParentNumber']= row.ParentNumber
objects_list.append(d)
output = {"MetaData": {},
"SRData": d}
print output
j = json.dumps(output)
print json.dumps(output, sort_keys=True, indent=4)`
Output for fetchall and fetchmany:
{
"MetaData": {},
"SRData": {
"FirstName": "MyLAG",
"LastName": "ThreeEleven",
"ParentNumber": "021720151654176723",
"SRNUMBER": "1-3580171"
}
}
Use code from my answer here to build a list of dictionaries for the value of output['SRData'], then JSON encode the output dict as normal.
import pyodbc
import json
connstr = 'DRIVER={SQL Server};SERVER=server;DATABASE=ServiceRequest; UID=SA;PWD=pwd'
conn = pyodbc.connect(connstr)
cursor = conn.cursor()
cursor.execute("""SELECT SRNUMBER, FirstName, LastName, ParentNumber FROM MYLA311""")
# build list of column names to use as dictionary keys from sql results
columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
results.append(dict(zip(columns, row)))
output = {"MetaData": {}, "SRData": results}
print(json.dumps(output, sort_keys=True, indent=4))
For starters, the line
objects_list.append(d)
needs to be inside the for loop, not outside.

Categories

Resources