Python doesn't retrieve data from mysql table - mysql

I am tried to retrieve entry_time from mysql table (named user) and then find the time difference between now (exitTime) and the entry_time. My code doesn't seem to recover the data from mysql table. f is the id search key for the code which searches against the ID (PRIMARY KEY) of the mysql database to find the corresponding entry_time.
I have tried taking it as a string as well to see if i could retrieve the value but to no avail.
from tkinter import *
import time,datetime
import mysql.connector as mc
from tkinter import messagebox
import cv2
import matplotlib.pyplot as plt
import sys
import time
def billCalc():
global exitTime
global EntryTime
EntryTime = datetime.datetime
exitTime = datetime.datetime.now()
try:
conn = mc.connect(host='localhost', user='root', password='', db='car_park_master')
except mc.Error as e:
print("Error %d: %s" % (e.args[0], e.args[1]))
sys.exit(1)
sql_Query = "SELECT `entry_time` FROM `user` WHERE `ID` ="+f.get()
#id = (f.get(),)
print(record[1])
cursor = conn.cursor(buffered=True)
cursor.execute(sql_Query, id)
record = cursor.fetchone()
# selecting column value into varible
EntryTime = datetime(record[1])
print(record[1])
conn.close()
print(exitTime)
print(EntryTime)
print(f.get())
BillTime = EntryTime - exitTime
Bill = BillTime * 2
print(Bill.get())
def main_screen():
screen = Tk()
screen.geometry("300x400")
screen.title("EXIT GATE")
global f
f = StringVar()
Entry(screen, textvariable=f).place(x=150, y=200)
print(f.get())
Button(screen,text="Exit",height='2',width='15',command=billCalc).place(x=150,y=300)
screen.mainloop()
main_screen()
It is supposed to take an exit time using datetime.datetime.now() which it does.
Then it is supposed to take input ID from the user to search in the database.
After that it is supposed to retrieve the corresponding entry time
Find the difference between entrytime and exit time in seconds
Then provide a bill.
EDITED AND FIXED CODE:
from tkinter import *
import datetime
import mysql.connector as mc
from tkinter import messagebox
import cv2
import matplotlib.pyplot as plt
import sys
import time
def billCalc():
global exitTime
global EntryTime
EntryTime = datetime.datetime
exitTime = datetime.datetime.now()
try:
conn = mc.connect(host='localhost', user='root', password='', db='car_park_master')
except mc.Error as e:
print("Error %d: %s" % (e.args[0], e.args[1]))
sys.exit(1)
cursor = conn.cursor()
cursor.execute("SELECT entry_time FROM user where id="+f.get())
record = cursor.fetchone()
EntryTime = (record[0])
conn.close()
print(exitTime)
print(EntryTime)
print(f.get())
BillTime = exitTime - EntryTime
print(BillTime)
def main_screen():
screen = Tk()
screen.geometry("300x400")
screen.title("EXIT GATE")
global f
f = StringVar()
Entry(screen, textvariable=f).place(x=150, y=200)
print(f.get())
Button(screen,text="Exit",height='2',width='15',command=billCalc).place(x=150,y=300)
screen.mainloop()
main_screen()

Related

sqlalchemy ORM Integrity error unique constraint failed: person.index

I have 2 csv files:
Person - with 2 columns(Index No: and Names) *running index number starting from 0
Infection- with 2 columns(From & To) *displays how from one index number infected to another index number. I written the following codes below, however i got an error :
"IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: person.index
[SQL: INSERT INTO person ("index", name) VALUES (?, ?)]
[parameters: (('INDEX_01', 'John Doe'), ('INDEX_02', 'Jane Doe'), and many more entries.
#Setting up the class
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Enum, Float, ForeignKey
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import relationship
Base = declarative_base()
class Person(Base):
__tablename__ = "person"
index = Column(String, primary_key=True)
name = Column(String)
paxrs = relationship("Infection", back_populates="rspax")
def __repr__(self):
return "%s %s" %(self.index, self.name)
class Infection(Base):
__tablename__ = 'infect'
fromwho = Column(String, primary_key=True)
towho = Column(String, ForeignKey('person.index'))
rspax = relationship("Person", back_populates="paxrs")
def __repr__(self):
return "%s %s" %(self.acqt_id, self.frompax, self.topax)
#Create database engine
engine = create_engine('sqlite:///test', echo=True)
engine
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
#Read the CSV files
import csv
with open('person.csv') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
people = Person(
index=row[0],
name=row[1]
)
session.add(people)
with open('infection.csv') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
spread = Infection(
fromwho=row[0],
towho=row[1],
)
session.add(spread)
session.commit()

How to get column names from a SQL query?

I need to put data from the SQL query into a Pandas dataframe. Please tell me is it possible to get column names the query results? I found that there is a keys() function in sqlalchemy for that but it does not work for me:
import mysql.connector
import pandas as pd
mydb = mysql.connector.connect(
host="SQLServer",
user="sqlusr",
password="usrpasswd",
database="sqldb"
)
cursor = mydb.cursor()
Query="SELECT Title, Review, Rate FROM reviews;"
cursor.execute(Query)
df = pd.DataFrame(cursor.fetchall())
df.columns = cursor.keys()
AttributeError: 'CMySQLCursor' object has no attribute 'keys'
I think that it your are searching for
cnx = mysql.connector.connect(user=DB_USER, password=DB_USER_PASSWORD, host=DB_HOST, database=DB_NAME)
cursor = cnx.cursor()
query = ("SELECT `name`, `ftp_name`, `created_at`, `status` AS `status_customer` FROM `customers"
"WHERE `status` = %(status)s")
cursor.execute(query, { 'status': 1 })
# cursor.description will give you a tuple of tuples where [0] for each is the column header.
num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
print(num_fields)
print(field_names)
>>> 4
>>> [u'name', u'ftp_name', 'created_at', u'status_customer']
# OR just use this cursor function:
print(cursor.column_names)
>>> (u'name', u'ftp_name', 'created_at', u'status_customer')
Hope this helps!
SHOW COLUMNS FROM your-database-name.your-table-name

Python: Faulty transfer from database output to Folium

I'm trying to read the coordinates from a MySQL database with Python and reproduce them on a map with Folium.
But I noticed that only the last of the 43 records are output and entered into the map and I don't know why.
I have the feeling that I can't see the wood for the trees anymore.
Maybe you can help me with how to read out all 43 data sets?
I have the complete code below including a screenshot of what this code outputs:
import folium
import mysql
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="",
database="firmen"
)
if(mydb):
print("Verbindung erfolgreich")
else:
print("Verbindung fehlgeschlagen")
cursor = mydb.cursor()
cursor.execute("SELECT * from leipzig")
result = cursor.fetchall()
cursor.close()
#13 = Longitude and 12 = Latitude
for data in result:
ID = data[0]
name = data[1]
lon = data[13]
lat = data[12]
mydb.close()
print("Verbindung geschlossen")
# Create a Map instance
mymap = folium.Map(location=[51.268360, 12.419357], tiles='stamentoner',
zoom_start=10, control_scale=True)
tooltipMeta = ID, name
folium.Marker([lon,lat], tooltip=tooltipMeta).add_to(mymap)
folium.TileLayer('stamenwatercolor').add_to(mymap)
folium.LayerControl().add_to(mymap)
# Display the map
mymap
#sentence & #borisdonchev are right, the part where
folium.Marker([lon,lat], tooltip=tooltipMeta).add_to(mymap)
should become
for data in result:
ID = data[0]
name = data[1]
lon = data[13]
lat = data[12]
tooltipMeta = ID, name
folium.Marker([lon,lat], tooltip=tooltipMeta).add_to(mymap)
I first had to create the map and then access the database.
So I managed to create the markers inside the loop
import folium
import mysql
import mysql.connector
mymap = folium.Map(location=[51.268360, 12.419357], tiles='stamentoner',
zoom_start=10, control_scale=True)
folium.TileLayer('stamenwatercolor').add_to(mymap)
folium.LayerControl().add_to(mymap)
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="",
database="firmen"
)
if(mydb):
print("Verbindung erfolgreich")
else:
print("Verbindung fehlgeschlagen")
cursor = mydb.cursor()
cursor.execute("SELECT * from leipzig")
result = cursor.fetchall()
cursor.close()
mydb.close()
print("Verbindung geschlossen")
#13 = Longitude and 12 = Latitude
for data in result:
ID = data[0]
name = data[1]
lon = data[13]
lat = data[12]
tooltipMeta = ID, name
folium.Marker([lon,lat], tooltip=tooltipMeta).add_to(mymap)
# Display the map
mymap

python mysql select in class

Unfortunately I've no Idea what's the issue coding in this way. I try to run a select statement within a class - the result is: TypeError: open_select() missing 1 required positional argument: 'query'.
Does anybody have an idea? Thx in advance
class finDB_exec:
def __init__(self):
self.dbcn = db.connect(host='localhost',
user='root',
password='xxx',
database='xxxx')
self.dbcr = self.dbcn.cursor()
def db_commit(self):
self.dbcn.commit()
def db_close(self):
self.dbcr.close()
self.dbcn.close()
##############################################################################
#### 1) Open Select
##############################################################################
def open_select(self,query):
try:
self.cr = self.dbcr()
self.cr.execute(query)
self.db_commit()
result = self.cursor.fetchall()
return result
except:
pass
query = 'Select * from tbl_companies limit 10'
res = finDB_exec.open_select(query)

SQLAlchemy insert many-to-one entries

Sorry, if this is a newbie question but the documentation about the many-to-one relationship doesn't seems to cover this. I have been looking for something similar to this (under the "How to Insert / Add Data to Your Tables" section), however in the shown example this is always a unique insertion.
Basically, I want to populate my database with data located on my local machine. For the sake of simplicity I have constructed the below-shown example into a MWE that illustrates the problem. The problem consists of two tables called Price and Currency and the implementation is done in a declarative style.
model.py
from sqlalchemy import Column, Integer, String
from sqlalchemy import Float, BigInteger, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Currency(Base):
__tablename__ = 'Currency'
id = Column(Integer, primary_key=True)
unit = Column(String(16), unique=True)
def __init__(self, unit):
self.unit = unit
class Price(Base):
__tablename__ = 'Price'
id = Column(BigInteger, primary_key=True)
currency_id = Column(Integer, ForeignKey("Currency.id"), nullable=False)
currency = relationship("Currency", backref="Currency.id")
hour1 = Column(Float)
hour2 = Column(Float)
def __init__(self, hour1, hour2):
self.hour1 = hour1
self.hour2 = hour2
Currently, I am populating the database using following code:
script.py
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from model import *
engine = create_engine('sqlite:///example.db', echo=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
session = db_session()
Base.metadata.create_all(engine)
oPrice = Price(2.5, 2.5)
oPrice.currency = Currency("EUR")
session.add(oPrice)
tPrice = Price(5.5, 1.5)
tPrice.currency = Currency("EUR")
session.add(tPrice)
session.commit()
This creates an error
sqlalchemy.exc.IntegrityError: (IntegrityError) column unit is not unique u'INSERT INTO "Currency" (unit) VALUES (?)' ('EUR',)
What is the best strategy for populating my database, such that I ensure that my Currency.id and Price.currency_id mapping is correct? Should I make the model-classes look for uniqueness before they are initialized, and do I do that in associated with the other table?
I'd second what Antti has suggested since currencies have standard codes like 'INR', 'USD' etc, you can make currency_code as primary key.
Or in case you want to keep the numeric primary key then one of the options is:
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject
edit (adding example based on the recipe in the link above, the one with class decoartor)
database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('sqlite:///example.db', echo=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
model.py
from sqlalchemy import Column, Integer, String
from sqlalchemy import Float, BigInteger, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
from database import db_session
Base = declarative_base()
def _unique(session, cls, hashfunc, queryfunc, constructor, arg, kw):
cache = getattr(session, '_unique_cache', None)
if cache is None:
session._unique_cache = cache = {}
key = (cls, hashfunc(*arg, **kw))
if key in cache:
return cache[key]
else:
with session.no_autoflush:
q = session.query(cls)
q = queryfunc(q, *arg, **kw)
obj = q.first()
if not obj:
obj = constructor(*arg, **kw)
session.add(obj)
cache[key] = obj
return obj
def unique_constructor(scoped_session, hashfunc, queryfunc):
def decorate(cls):
def _null_init(self, *arg, **kw):
pass
def __new__(cls, bases, *arg, **kw):
# no-op __new__(), called
# by the loading procedure
if not arg and not kw:
return object.__new__(cls)
session = scoped_session()
def constructor(*arg, **kw):
obj = object.__new__(cls)
obj._init(*arg, **kw)
return obj
return _unique(
session,
cls,
hashfunc,
queryfunc,
constructor,
arg, kw
)
# note: cls must be already mapped for this part to work
cls._init = cls.__init__
cls.__init__ = _null_init
cls.__new__ = classmethod(__new__)
return cls
return decorate
#unique_constructor(
db_session,
lambda unit: unit,
lambda query, unit: query.filter(Currency.unit == unit)
)
class Currency(Base):
__tablename__ = 'Currency'
id = Column(Integer, primary_key=True)
unit = Column(String(16), unique=True)
def __init__(self, unit):
self.unit = unit
class Price(Base):
__tablename__ = 'Price'
id = Column(BigInteger, primary_key=True)
currency_id = Column(Integer, ForeignKey("Currency.id"), nullable=False)
currency = relationship("Currency", backref="Currency.id")
hour1 = Column(Float)
hour2 = Column(Float)
def __init__(self, hour1, hour2):
self.hour1 = hour1
self.hour2 = hour2
script.py:
from model import *
from database import engine, db_session as session
Base.metadata.create_all(engine)
oPrice = Price(2.5, 2.5)
oPrice.currency = Currency("EUR")
session.add(oPrice)
tPrice = Price(5.5, 1.5)
tPrice.currency = Currency("EUR")
session.add(tPrice)
session.commit()
The best simplest solution is to use the currency codes as the primary keys in Currency, and foreign keys in Price. Then you can have
price.currency_id = "EUR"
This also makes your database tables more readable - as in you won't have 28342 but 'GBP'.