Mongoengine flask get dbstats - python

Cannot figure out how to get db.stats in Mongoengine.
I've tried:
db = MongoEngine()
db.stats()
Also
db.Document.objects.stats()
db.Document.stats()
Also tried to execute JS, but nothing works and documentation is very poor.

db.stats it is a mongo's shell method
You can try something like that:
from mongoengine.connection import get_connection
con = get_connection()
con.get_database().eval('db.stats()')
con.get_database().eval('db.getCollectionInfos()')
Also I advise you to examine objects with dir method, sometimes it could be useful:
from pprint import pprint
pprint(dir(con))

MongoEngine is a wrapper for PyMongo. So to get the stats of a mongo database using mongoengine you could run the 'dbstats' mongodb api command on the database, using the pymongo command funtion like this:
from mongoengine import connect
client = connect()
db = client.get_database('your_database_name')
db_stats = db.command('dbstat')
coll_stats = db.command('collstats', 'your_colletion_name')
print(db_stats)
print(coll_stats)

Related

Where the command client.stats comes from in Python driver?

I'm following MongoDB university course M220, on using Python with MongoDB.
It starts with defining the connection:
from pymongo import MongoClient
uri = "mongodb+srv://m220student:m220password#mflix.abcde.mongodb.net"
client = MongoClient(uri)
And then it uses client.stats
That gives:
Database(MongoClient(host=['mflix-shard-00-01.abcde.mongodb.net:27017', 'mflix-shard-00-00.9go7j.mongodb.net:27017', 'mflix-shard-00-02.9go7j.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=True, authsource='admin', replicaset='atlas-js08eu-shard-0', ssl=True), 'stats')
I can't figure out where the stats comes from?
There is nothing in MongoDB API documentation. I even unpacked and searched the source code wheel file and couldn't find it.
You created an instance of the mongo db client, thus you have access to the db.stats() method:
Here's the documentation for that method:
https://docs.mongodb.com/manual/reference/method/db.stats/

Invoke method on SQLite connection in Flask-SQLAlchemy

I'm developing a web app with Flask-SQLAlchemy backed by a SQLite database. I need to call a method (create_collation) right after connecting. Without the SQLAlchemy framework, I can do that like this:
conn = sqlite3.connect(path)
conn.create_collation('my_collate', my_collate)
# ... go on and do fancy "order_by" stuff.
How do I do that in Flask-SQLAlchemy? Based on the API I was thinking of the following, but I get AttributeError: 'Engine' object has no attribute 'create_collation'.
from flask_sqlalchemy import SQLAlchemy
class MySQLAlchemy(SQLAlchemy):
def create_engine(self, sa_url, engine_opts):
engine = super().create_engine(sa_url, engine_opts)
engine.create_collation('my_collate', self.my_collate)
return engine
#staticmethod
def my_collate(string1, string2):
return string1.locateCompare(string2)
Following the SQLAlchemy docs I think I need to get the connection rather than the engine. But I can't find out how.
Also, where should this go specifically in Flask-SQLAlchemy? What part ultimately "connect"s, and how do I tune into that?
SQLAlchemy has an Events API that allows you to create a function that will be called whenever the connection pool creates a new connection:
from sqlalchemy.event import listens_for
from sqlalchemy.pool import Pool
#listens_for(Pool, "connect")
def my_on_connect(dbapi_con, connection_record):
dbapi_con.create_collation('my_collate', my_collate)

$inc operator not working in my flask app using mongodb atlas

I'm looking to increment the 'views' field by +1 in my document within my collection. I'm using mongodb atlas database to be included in my flask app. I've included my route here. Any suggestions would be great thanks.
#app.route('/view_count/<recipe_id>', methods=['POST'])
def view_count(recipe_id):
mongo.db.recipes.update_one({"_id": ObjectId(recipe_id)}, {"$inc": {'views': 1}})
return redirect(url_for('view_recipe.html'))
you queries are correct if you are using pymongo.
maybe, the problem are mongo.db.
Example
from bson import ObjectId
from pymongo import MongoClient
# connect to general db
client = MongoClient('mongodb://localhost:27017')
# mongo accept everything, so is ok these queries below
# OBS: client.db means connection with database called db inside mongo
client.db.recipes.insert_one({'_id':ObjectId(), 'views': 0})
client.db.recipes.find_one({}) # the insertion above work
client.db.recipes.update_one({}, {'$inc': {'views': 1}}) # have only one, so update they
but if you change:
client = MongoClient('mongodb://localhost:27017')
# with
client = MongoClient('mongodb://localhost:27017').db
# everything continue working, but now, the path to recipes is db.db.db.recipes

How to cache SQL Alchemy calls with Flask-Cache and Redis?

I have a Flask app that takes parameters from a web form, queries a DB with SQL Alchemy and returns Jinja-generated HTML showing a table with the results. I want to cache the calls to the DB. I looked into Redis (Using redis as an LRU cache for postgres), which led me to http://pythonhosted.org/Flask-Cache/.
Now I am trying to use Redis + Flask-Cache to cache the calls to the DB. Based on the Flask-Cache docs, it seems like I need to set up a custom Redis cache.
class RedisCache(BaseCache):
def __init__(self, servers, default_timeout=500):
pass
def redis(app, config, args, kwargs):
args.append(app.config['REDIS_SERVERS'])
return RedisCache(*args, **kwargs)
From there I would need to something like:
# not sure what to put for args or kwargs
cache = redis(app, config={'CACHE_TYPE': 'redis'})
app = Flask(__name__)
cache.init_app(app)
I have two questions:
What do I put for args and kwargs? What do these mean? How do I set up a Redis cache with Flask-Cache?
Once the cache is set up, it seems like I would want to somehow "memoize" the calls the DB so that if the method gets the same query it has the output cached. How do I do this? My best guess would be to wrap the call the SQL Alchemy in a method that could then be given memoize decorator? That way if two identical queries were passed to the method, Flask-Cache would recognize this and return to the appropriate response. I'm guessing that it would look like this:
#cache.memoize(timeout=50)
def queryDB(q):
return q.all()
This seems like a fairly common use of Redis + Flask + Flask-Cache + SQL Alchemy, but I am unable to find a complete example to follow. If someone could post one, that would be super helpful -- but for me and for others down the line.
You don't need to create custom RedisCache class. The docs is just teaching how you would create new backends that are not available in flask-cache. But RedisCache is already available in werkzeug >= 0.7, which you might have already installed because it is one of the core dependencies of flask.
This is how I could run the flask-cache with redis backend:
import time
from flask import Flask
from flask_cache import Cache
app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'redis'})
#cache.memoize(timeout=60)
def query_db():
time.sleep(5)
return "Results from DB"
#app.route('/')
def index():
return query_db()
app.run(debug=True)
The reason you're getting "ImportError: redis is not a valid FlaskCache backend" is probably because you don't have redis (python library) installed which you can simply install by:
pip install redis.
your redis args would look something like this:
cache = Cache(app, config={
'CACHE_TYPE': 'redis',
'CACHE_KEY_PREFIX': 'fcache',
'CACHE_REDIS_HOST': 'localhost',
'CACHE_REDIS_PORT': '6379',
'CACHE_REDIS_URL': 'redis://localhost:6379'
})
Putting the #cache.memoize over a method that grabs the info from the DB should work.

How to create a test script in Python for a registration page?

I have a website made in PHP.
To increase number of data sets in my database, I need to create a python script such that I need not add 500 registrations manually.
There are several tools available but I need to create script of my own.
Can any one help me with this ?
PS: I have knowledge of PHP, Python and ASP.NET as well.
MySQL
import MySQLdb
db = MySQLdb.connect(host="localhost", user="john", passwd="megajonhy", db="jonhydb")
cursor = db.cursor()
for i in range(0,500):
cursor.execute("INSERT INTO MyTable VALUES('Some string', 1337);")
PostgreSQL
import postgresql
db = postgresql.open("pq://postgres:SupaPass#127.0.0.1/testdb")
prepstatement = db.prepare("INSERT INTO MyTable VALUES($1, $2, $3);")
with db.xact():
for i in range(0, 500):
prepstatement('Some string', 1337, ["a", "list"])
MsSQL
import pyodbc
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=user;PWD=pass')
cursor = cnxn.cursor()
for i in range(0, 500):
cursor.execute("INSERT INTO MyTable VALUES('Some string', 1337);")
SQLAlchemy
Note that this is a library that will do a lot of magic for you, hence you'd might not learn as much from it or desire all it's functionality.
from sqlalchemy import create_engine
db = create_engine("mssql://me:pass#localhost/testdb")
for i in range(0, 500):
db.execute("INSERT INTO MyTable VALUES('Some string', 1337);"):
How get get POST/GET data
And finally, we have no clue as to how you run the script.
But you mentioned web development and well, assuming you run the script as CGI, here's how to get the POST/GET data:
import cgi
form = cgi.FieldStorage()
print form["username"]
Let me Google this for you
How are POST and GET variables handled in Python?
How do I connect to a MySQL Database in Python?
How to insert array of data into mysql using php
MSSQL in python 2.7
You'll find a lot of Web testing tools in this page: https://wiki.python.org/moin/PythonTestingToolsTaxonomy#Web_Testing_Tools
However I would like to recommend another python module.
I understood that the script python will access to your web page and It'll simulate a human registration, if this assumption is right, you can use "requests" module, It's not a testing tool exactly, but It's a very easy way to access and recover web content, for instance:
You can manage http session (source: http://docs.python-requests.org/en/latest/user/advanced/#session-objects):
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
# both 'x-test' and 'x-test2' are sent
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
An whatever authentication method (source: http://docs.python-requests.org/en/latest/user/authentication/):
>>> from requests.auth import HTTPDigestAuth
>>> url = 'http://httpbin.org/digest-auth/auth/user/pass'
>>> requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
<Response [200]>

Categories

Resources