As the title states, I'm trying to insert a date (formatted as a string) into a SQLite database. This works, however the date is not showing up correctly in SQLite.
Here is a subset of my code:
print("Connecting to the database...")
sqlite_file = './sqlite_db/cfr_changes.db'
conn = sqlite3.connect(sqlite_file)
c = conn.cursor()
today_date = datetime.now().strftime("%Y-%m-%d")
print(today_date)
print("Inserting tracker into database...")
c.execute("INSERT INTO DATE (`date_id`) VALUES(" + today_date + ")")
c.executemany("INSERT INTO TRACKER (`cfr_status`, `comment`, `mdu`, `iwb`, `obsolete`, `date_id`) VALUES(?,?,?,?,?, " + today_date + ")", list(tracker_df.to_records(index=False)))
#print(c.fetchall())
conn.commit()
conn.close()
Printing 'today_date' returns what I'd expect:
2018-10-24
However when I check the records in SQLite through the terminal, the date is shown as:
1984
Note that 'date_id' is a VARCHAR(255), and date formatting should not be an issue. I would think that is simply a string being stored into a string (or close enough).
Can anyone inform me why this doesn't work as expected?
For reference, here is how the 'TRACKER' and 'DATE' tables were created:
CREATE TABLE `DATE` (
`date_id` VARCHAR(255) NOT NULL PRIMARY KEY);
CREATE TABLE `TRACKER` (
`tracker_id` INTEGER NOT NULL PRIMARY KEY,
`cfr_status` VARCHAR(255) NOT NULL,
`mdu` BOOLEAN, `iwb` BOOLEAN,
`obsolete` BOOLEAN, `comment` VARCHAR(255), `date_id` VARCHAR(255) NOT NULL, FOREIGN KEY (`date_id`) REFERENCES DATE(`date_id`));
Any help is appreciated.
The issue is that you are just concatenating variables into your insert statements without worrying about whether the format they are in makes any sense. For example, to insert a date literal into SQLite you should be using this:
'2018-10-24'
Here is an example of how you may use prepared statements to do a proper insert:
today_date = datetime.now().strftime("%Y-%m-%d")
c.execute("INSERT INTO DATE (date_id) VALUES (?)", ("'" + today_date + "'",))
Related
So I'm trying to make a project for school where a database stores the check_in and check_out time form an RFID card using a RFID reader.
create table attendance_check(
id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
date_id DATE NOT NULL DEFAULT CURRENT_DATE,
user_id INT UNSIGNED NOT NULL,
name VARCHAR(255) NOT NULL,
clock_id TIME NOT NULL DEFAULT CURRENT_TIME,
Action VARCHAR(255) NOT NULL,
PRIMARY KEY ( id )
);
The database looks like this and for "Action" I want to add "in" and "out". I manage to add the "in" but can't figure out how to make a look-up and add an "out".
This is the code so far. I've tried 10 different variations already, I also have a database that stores the Users.
while True:
lcd.clear()
lcd.message('Place Card to\nrecord attendance')
id, text = reader.read()
cursor.execute("Select id, name FROM users WHERE rfid_uid="+str(id))
result = cursor.fetchone()
lcd.clear()
name = result[1]
number = result [0]
action1 = "in"
action2 = "out"
if cursor.rowcount >= 1:
lcd.message("Welcome " + name)
add = ("INSERT INTO attendance_check (user_id, name, Action) VALUES (%s, %s, %s)")
date = (numar, nume, action1)
cursor.execute(add, date)
db.commit()
else:
lcd.message("User does not exist.")
time.sleep(2)
I've tried to use if statements inside that checks if an action is there and if it's "in" it should add "out" but it never worked
It looks like this so far
Error Message
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near '%s' at line 1
MySQL Database Table
CREATE TABLE `tblorders` (
`order_id` int(11) NOT NULL,
`order_date` date NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `tblorders`
ADD PRIMARY KEY (`order_id`),
ADD UNIQUE KEY `order_number` (`order_number`);
ALTER TABLE `tblorders`
MODIFY `order_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
Code
mydb = mysql.connector.connect(host = "localhost", user = "root", password = "", database = "mydb")
mycursor = mydb.cursor()
sql = "Select order_id from tblorders where order_number=%s"
val = ("1221212")
mycursor.execute(sql, val)
Am I missing anything?
You must pass a list or a tuple as the arguments, but a tuple of a single value is just a scalar in parentheses.
Here are some workarounds to ensure that val is interpreted as a tuple or a list:
sql = "Select order_id from tblorders where order_number=%s"
val = ("1221212",)
mycursor.execute(sql, val)
sql = "Select order_id from tblorders where order_number=%s"
val = ["1221212"]
mycursor.execute(sql, val)
This is a thing about Python that I always find weird, but it makes a kind of sense.
In case you want to insert data you have to modify your SQL. Use INSERT instead of SELECT like this:
INSERT INTO tblorders (order_number) VALUES ("122121");
That statement will add new record to the table. Besides, in MariaDB you need to use ? instead of %s that works on Mysql database.
sql = "INSERT INTO tblorders (order_number) VALUES (?);"
val = "1231231"
mycursor.execute(sql, [val])
As the title says, I'm having problems retrieving data from a SQLite DB when using WHERE statement.
Here is the piece of code that tries to get a row where an ID is given:
def check_attendance(self, cred):
query = """SELECT * FROM clients WHERE dni=?"""
self.conn.cursor().execute(query, (cred,))
record = self.conn.cursor().fetchone()
The var cred is already inside a tuple as specified by SQLite API for Python. Sadly, the query returns None when executed here.
If I do the same but using sqlite.exe, then I do get the right row back. In fact, this is the only query I cannot execute properly from my python script, everything else return rows normally.
Here it is executing from the Python script
And here is in sqlite.exe
Here is the piece that stores values in the DB:
def new_client(self, *args):
success = False
# Check if all inputs are filled
if self.dialog.content_cls.ids.user_name.text and self.dialog.content_cls.ids.user_surname.text and len(self.dialog.content_cls.ids.user_dni.text) == 8 and self.dialog.content_cls.ids.user_date.text:
# Convert str date to a datetime obj in order to use it with timedelta
paid_date = datetime.strptime(self.dialog.content_cls.ids.user_date.text, "%d-%m-%Y")
# paid_date is now YYYY-MM-DD HH-MM-SS format
# Add 30 days to paid_date
exp_date = paid_date + timedelta(days=30)
# Convert YYYY-MM-DD HH-MM-DD to string YYYY-MM-DD as we don't need clock
paid_date = datetime.strptime(str(paid_date), "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")
exp_date = datetime.strptime(str(exp_date), "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")
# Create query blueprint and try executing
query = """INSERT INTO clients (name, surname, dni, membership_date, expiration_date) VALUES (?,?,?,?,?)"""
try:
self.conn.execute(query, (self.dialog.content_cls.ids.user_name.text,
self.dialog.content_cls.ids.user_surname.text,
self.dialog.content_cls.ids.user_dni.text,
paid_date,
exp_date
)
)
success = True
except sqlite3.IntegrityError:
pass
if success:
self.conn.commit()
The try/except was used for other reasons. Adding to the database from the Python script works fine as shown in the second screenshot.
And the table clients is as follows:
c.execute(''' CREATE TABLE clients (id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
surname TEXT NOT NULL,
dni INTEGER NOT NULL UNIQUE,
membership_date date NOT NULL,
expiration_date date NOT NULL); ''')
Using Python v3.7.7 32bit.
Thanks!
In your code, the cursor is initialized two times (cursor()).
You should either get the results from the same cursor you used to execute the SELECT statement:
def check_attendance(self, cred):
query = """SELECT * FROM clients WHERE dni=?"""
cur = self.conn.cursor()
cur.execute(query, (cred,))
record = cur.fetchone()
...or you can avoid the implicit cursor creation by using execute method directly on Connection object:
def check_attendance(self, cred):
query = """SELECT * FROM clients WHERE dni=?"""
record = self.conn.execute(query, (cred,)).fetchone()
You can read more about this approach in the documentation (https://docs.python.org/3/library/sqlite3.html#using-sqlite3-efficiently):
Using the nonstandard execute(), executemany() and executescript() methods of the Connection object, your code can be written more concisely because you don’t have to create the (often superfluous) Cursor objects explicitly. Instead, the Cursor objects are created implicitly and these shortcut methods return the cursor objects.
I have that query in a python program:
And i should create a multidimensional array (if it possible) or four arrays from this query for every column from the query.
Can you suggest an elegant way to solve it?
conn = #connection to the server
cursor=conn.cursor()
query = (" select id, name, phone, city from guest")
cursor.execute(query)
results = cursor.fetchall
for i in results:
print i
cursor.close()
conn.close()
Not elegant but it may assist to unravel the mysterious Python Connector Cursor Class and transfers the list of tuples (see Copperfield comment) with the data from the query, into a list (phoneList) of dictionaries (entries) with details of each entry in the database, that might be easier to work with in your python script:
# ref: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor.html
import mysql.connector
db = 'test'
table = 'phonebook'
phoneList = []
drop_table = ("DROP TABLE IF EXISTS {};").format(table)
# By default, the starting value for AUTO_INCREMENT is 1, and it will increment by 1 for each new record.
# To let the AUTO_INCREMENT sequence start with another value, use the following SQL statement:
# ALTER TABLE phonebook AUTO_INCREMENT=100;
create_table = ("CREATE TABLE {} ("
"id int NOT NULL AUTO_INCREMENT,"
"name varchar(30) NOT NULL,"
"phone varchar(30) NOT NULL,"
"city varchar(30) NOT NULL,"
"PRIMARY KEY (id))"
" ENGINE=InnoDB DEFAULT CHARSET=latin1;").format(table)
Names = {'Bill':{'phone':'55123123','city':'Melbourne'},
'Mary':{'phone':'77111123','city':'Sydney'},
'Sue':{'phone':'55888123','city':'Melbourne'},
'Harry':{'phone':'77777123','city':'Sydney'},
'Fred':{'phone':'88123444','city':'Yongala'},
'Peter':{'phone':'55999123','city':'Melbourne'}}
cnx = mysql.connector.connect(user='mysqluser', password='xxxx',host='127.0.0.1',database=db)
cursor = cnx.cursor(dictionary=True) # key to using **row format
cursor.execute(drop_table)
cursor.execute(create_table)
# populate db
for name,detail in dict.items(Names):
sql = ("INSERT INTO {} (name,phone,city) VALUES ('{}','{}','{}')".format(table,name,detail['phone'],detail['city']))
cursor.execute(sql)
sql = ("SELECT id,name,phone,city FROM {}".format(table))
cursor.execute(sql)
for row in cursor:
print("{id} {name} {phone} {city}".format(**row))
phoneList.append(row)
print phoneList[0]['name'],phoneList[0]['city']
print phoneList[3]['name'],phoneList[3]['phone']
for entries in phoneList: # list of dictionaries
print entries['name'],entries
for entries in phoneList:
for k,v in dict.items(entries):
print k,v
print "\n"
cnx.close()
I want to create a new mysqldb table for each unique user, but i'm getting errors:
1.'bytes' object has no attribute 'encode'
2.Can't convert 'bytes' object to str implicitly
3.You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Text'(
id int(11) NOT NULL AUTO_INCREMENT,
UserName text NOT NULL' at line 1
c.execute("CREATE TABLE IF NOT EXISTS {table_name}".format(table_name=belekas), (belekas) + """(
`id` int(11) NOT NULL AUTO_INCREMENT,
`UserName` text NOT NULL,
`Data` date NOT NULL,
`Laikas` time NOT NULL,
`KeyStrokes` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8""")
con.commit()
c.execute("INSERT INTO {table_name} VALUES (id, %s, Data, Laikas, %s)".format(table_name=belekas),
(belekas, vartotojas, tekstas))
con.commit()
I tried using:
c.execute("CREATE TABLE IF NOT EXISTS" + vartotojas + """(
and this:
c.execute("CREATE TABLE IF NOT EXISTS" + repr(vartotojas.decode('utf-8')) + """(
and this:
c.execute("CREATE TABLE IF NOT EXISTS {this_table}".format(this_table=vartotojas), (vartotojas.encode("utf-8")) + """(
Can someone suggest solution for this problem?