I am trying to write a backend that will be used for an IOS app. I know it will be technically the wrong way to do it but it wont be deployed.
My issues is i get the error
self.cursor(query)
TypeError: 'CMySQLCursor' object is not callable
This happens when i run the following from main.py
import database
db = database.database()
staff = db.getData("SELECT * FROM timesheets.staff")
Finally this is my database.py code
import mysql.connector
class database :
conn = ""
cursor = ""
def __init__(self):
self.conn = mysql.connector.connect(user='james',
password='timeismoney',
host='hallfamily.mycrestron.com',
database='timesheets',
port='6033')
self.cursor = self.conn.cursor()
print("Done")
def getData(self, query):
#Checking if the user has applied a string
if isinstance(query, str):
self.cursor(query)
else:
return "You have provided a request that cant be processed"
#Fetching all the results
result = self.cursor.fetchall()
#Returning back to the user
return result
def postData(self):
print("Coming soon")
def close(self):
self.conn.close()
Instead of:
self.cursor(query)
Try this:
self.cursor.execute(query)
Related
I don't know how to write a Lambda. Here is my main_script.py that executes 2 stored procedures. It inserts records every day then finds the difference between yesterday's and today's records and writes them to a table.
import logging
import pymysql as pm
import os
import json
class className:
env=None
config=None
def __init__(self, env_filename):
self.env=env_filename
self.config=self.get_config()
def get_config(self):
with open(self.env) as file_in:
return json.load(file_in)
def DB_connection(self):
config=className.get_config(self)
username=config["exceptions"]["database-secrets"]["aws_secret_username"]
password=config["exceptions"]["database-secrets"]["aws_secret_password"]
host=config["exceptions"]["database-secrets"]["aws_secret_host"]
port=config["exceptions"]["database-secrets"]["aws_secret_port"]
database=config["exceptions"]["database-secrets"]["aws_secret_db"]
return pm.connect(
user=username,
password=password,
host=host,
port=port,
database=database
)
def run_all(self):
def test_function(self):
test_function_INSERT_QUERY = "CALL sp_test_insert();"
test_function_EXCEPTIONS_QUERY = "CALL sp_test_exceptions();"
test = self.config["exceptions"]["functions"]["test_function"]
if test:
with self.DB_connection() as cnxn:
with cnxn.cursor() as cur:
try:
cur.execute(test_function_INSERT_QUERY)
print("test_function_INSERT_QUERY insertion query ran successfully, {} records updated.".format(cur.rowcount))
cur.execute(test_function_EXCEPTIONS_QUERY)
print("test_function_EXCEPTIONS_QUERY exceptions query ran successfully, {} exceptions updated.".format(cur.rowcount))
except pm.Error as e:
print(f"Error: {e}")
except Exception as e:
logging.exception(e)
else:
cnxn.commit()
test_function(self)
def main():
cwd=os.getcwd()
vfc=(cwd+"\_config"+".json")
ve=className(vfc)
ve.run_all()
if __name__ == "__main__":
main()
Would I write my lambda_handler function inside my script above or have it as a separate script?
def lambda_handler(event, context):
#some code
I would treat lambda_handler(event, context) as the equivalent of main() with the exception that you do not need if __name__ ... clause because you never run a lambda function from the console.
You would also need to use boto3 library to abstract away AWS services and their functions. Have a look at the tutorial to get started.
As the first order of business, I would put the DB credentials out of the file system and into a secure datastore. You can of course configure Lambda environment variables, but Systems Manager Parameter Store is more secure and super-easy to call from the code, e.g.:
import boto3
ssm = boto3.client('ssm', region_name='us-east-1')
def lambda_handler(event, context):
password = ssm.get_parameters(Names=['/pathto/password'], WithDecryption=True)['Parameters'][0]['Value']
return {"password": password}
There is a more advanced option, the Secrets Manager, which for a little money will even rotate passwords for you (because it is fully integrated with Relational Database Service).
I write some tests with pytest, I want to test create user and email with post method.
With some debug, I know the issue is I open two databases in memory, but they are same database SessionLocal().
So how can I fix this, I try db.flush(), but it doesn't work.
this is the post method code
#router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(deps.get_db), #the get_db is SessionLocal()
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
user = crud.user.get_by_email(db, email=user_in.email)
if user:
raise HTTPException(
status_code=400,
detail="The user with this username already exists in the system.",
)
user = crud.user.create(db, obj_in=user_in)
print("====post====")
print(db.query(models.User).count())
print(db)
if settings.EMAILS_ENABLED and user_in.email:
send_new_account_email(
email_to=user_in.email, username=user_in.email, password=user_in.password
)
return user
and the test code is:
def test_create_user_new_email(
client: TestClient, superuser_token_headers: dict, db: Session # db is SessionLocal()
) -> None:
username = random_email()
password = random_lower_string()
data = {"email": username, "password": password}
r = client.post(
f"{settings.API_V1_STR}/users/", headers=superuser_token_headers, json=data,
)
assert 200 <= r.status_code < 300
created_user = r.json()
print("====test====")
print(db.query(User).count())
print(db)
user = crud.user.get_by_email(db, email=username)
assert user
assert user.email == created_user["email"]
and the test result is
> assert user
E assert None
====post====
320
<sqlalchemy.orm.session.Session object at 0x7f0a9f660910>
====test====
319
<sqlalchemy.orm.session.Session object at 0x7f0aa09c4d60>
Your code does not provide enough information to help you, the key issues are probably in what is hidden and explained by your comments.
And it seems like you are confusing sqlalchemy session and databases. If you are not familiar with these concepts, I highly recommend you to have a look at SQLAlchemy documentation.
But, looking at your code structure, it seems like you are using FastAPI.
Then, if you want to test SQLAlchemy with pytest, I recommend you to use pytest fixture with SQL transactions.
Here is my suggestion on how to implement such a test. I'll suppose that you want to run the test on your actual database and not create a new database especially for the tests. This implementation is heavily based on this github gist (the author made a "feel free to use statement", so I suppose he is ok with me copying his code here):
# test.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from fastapi.testclient import TestClient
from myapp.models import BaseModel
from myapp.main import app # import your fastapi app
from myapp.database import get_db # import the dependency
client = TestClient(app)
# scope="session" mean that the engine will last for the whole test session
#pytest.fixture(scope="session")
def engine():
return create_engine("postgresql://localhost/test_database")
# at the end of the test session drops the created metadata using fixture with yield
#pytest.fixture(scope="session")
def tables(engine):
BaseModel.metadata.create_all(engine)
yield
BaseModel.metadata.drop_all(engine)
# here scope="function" (by default) so each time a test finished, the database is cleaned
#pytest.fixture
def dbsession(engine, tables):
"""Returns an sqlalchemy session, and after the test tears down everything properly."""
connection = engine.connect()
# begin the nested transaction
transaction = connection.begin()
# use the connection with the already started transaction
session = Session(bind=connection)
yield session
session.close()
# roll back the broader transaction
transaction.rollback()
# put back the connection to the connection pool
connection.close()
## end of the gist.github code
#pytest.fixture
def db_fastapi(dbsession):
def override_get_db():
db = dbsession
try:
yield db
finally:
db.close()
client.app.dependency_overrides[get_db] = override_get_db
yield db
# Now you can run your test
def test_create_user_new_email(db_fastapi):
username = random_email()
# ...
I'm trying to use Bottle framework in python with sqlite3. Then I made a Todo List application but when I tried to post a data at the first time the error happened differently from above. The second time 'database is locked' happened.
Can anyone help?
#_*_ coding:utf-8- _*_
import os, sqlite3
from bottle import route, run, get, post, request, template
#sqlite from here----------------
dbname = "todo.db"
connection = sqlite3.connect(dbname)
dbcontrol = connection.cursor()
#Making table from here--------------------
create_table = '''create table todo_list (todo text)'''
#route("/")
def index():
todo_list = get_todo()
return template("index", todo_list=todo_list)
I think I need more specific code here.
#route("/enter", method=["POST"])
def enter():
conn = sqlite3.connect("todo.db")
todo=request.POST.getunicode("todo_list")
save_todo(todo)
return redirect("/")
def save_todo(todo):
connection = sqlite3.connect('todo.db')
dbcontrol = connection.cursor()
insert="insert into todo_list(todo) values('{0}')".format(todo)
dbcontrol.execute(insert)
connection.commit()
def get_todo():
connection=sqlite3.connect('todo.db')
dbcontrol = connection.cursor()
select = "select * from todo_list"
dbcontrol.execute(select)
row = dbcontrol.fetchall()
return row
run(host="localhost", port=8080, debug=True)
Install the bottle-sqlite with:
$ pip install bottle-sqlite
An example from the plugin
import bottle
app = bottle.Bottle()
plugin = bottle.ext.sqlite.Plugin(dbfile='/tmp/test.db')
app.install(plugin)
#app.route('/show/:item')
def show(item, db):
row = db.execute('SELECT * from items where name=?', item).fetchone()
if row:
return template('showitem', page=row)
return HTTPError(404, "Page not found")
Important notes from the plugin
Routes that do not expect a db keyword argument are not affected.
The connection handle is configured so that sqlite3.Row objects can be
accessed both by index (like tuples) and case-insensitively by name.
At the end of the request cycle, outstanding transactions are
committed and the connection is closed automatically. If an error
occurs, any changes to the database since the last commit are rolled
back to keep the database in a consistent state.
Also take a look at Configuration section.
I want to connect to a postgresql server with peewee but I keep getting a error that I need a password but I have no clue how to add it current transaction is aborted, commands ignored until end of transaction block
.I have read every bit of the docs and still have no clue how. If I can't help i'll just go to sqlite.
from twython import Twython, TwythonError
import json
from peewee import *
"""Setting up variables"""
db = PostgresqlDatabase("Tweets",user='postgres')
Cred_Filename = 'Keys.json'
jf = open(Cred_Filename)
creds = json.load(jf)
jf.close()
twitter = Twython(creds['consumer_key'],
creds['consumer_secret'],
creds['access_token'],
creds['access_token_secret'])
"""End of variables"""
"""PostgreSql Setup"""
class BaseModel(Model):
"""A base model that will use our Postgresql database"""
class Meta:
database = db
class Tweet(BaseModel):
tweet = CharField()
try:
Tweet.create_table()
except Exception as e:
pass
"""End of PostgreSql Setup"""
"""Pulling Tweets and displaying them"""
def PullTweet():
"""Take user input and pull and print 10 newest tweets"""
user_input = input('Please Enter A Username: ')
try:
user_timeline = twitter.get_user_timeline(screen_name=user_input)
except TwythonError as e:
print(e)
print(user_input)
for tweets in user_timeline:
print('[*]' + tweets['text'])
try:
tweet = Tweet(tweet=tweets['text'])
tweet.save()
except Exception as e:
print(e)
PullTweet()
PostgresqlDatabase just passes additional kwargs through to psycopg2.connect, and that signature looks like
conn = psycopg2.connect(dbname="test", user="postgres", password="secret")
So you just need to add a password kwarg to your call:
db = PostgresqlDatabase("Tweets",user='postgres', password='***')
Note, though, that it's generally not safe to store your database password in plain text within your program.
I am trying to test by mocking a database query, but receiving an error:
Asssertion error:AssertionError: Expected call: execute()
Not called
and create_table() not defined.
I want to execute() to be called and use create_table() to return response for asserting against pre-defined values.
app.py
from flask import Flask,g
#app.before_request
def before_request():
g.db = mysql.connector.connect(user='root', password='root', database='mysql')
def create_table():
try:
cur = g.db.cursor() #here g is imported form Flask module
cursor.execute ('CREATE TABLE IF NOT EXISTS Man (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(40)')
data = dict(Table='Man is created')
resp = jsonify(data)
cursor.close()
return resp
test.py
import unittest
from app import *
from mock import patch
class Test(unittest.TestCase):
def test_create(self):
with patch("app.g") as mock_g:
mock_g.db.cursor()
mock_g.execute.assert_called_with()
resp = create_table()
assertEqual(json, '{"Table":"Testmysql is created","Columns": ["id","name","email"]}')
What am I doing wrong?Can someone please tell me how to fix it
I believe you need to add your changes before closing the cursor, or the execute won't occur. Try adding cursor.commit() before (or instead of) cursor.close().