Flask, SQLAlchemy: How to make column autoincrement - sqlite

I'm defining a model like this:
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
first = db.Column(db.String(64))
last = db.Column(db.String(64))
dob = db.Column(db.Date)
street_addr1 = db.Column(db.String(64))
street_addr2 = db.Column(db.String(64))
city = db.Column(db.String(64))
state = db.Column(db.String(2))
zip = db.Column(db.String(9))
gender = db.Column(db.Enum('M', 'F'))
home_box = db.Column(db.String(32))
username = db.Column(db.String(64), unique=True, index=True)
password_hash = db.Column(db.String(128))
#property
def password(self):
raise AttributeError('password is not a readable attribute')
#password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
def __repr__(self):
return '<User %r>' % self.username
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
views.py:
#main.route('/', methods=['GET', 'POST'])
def index():
form = RegistrationForm()
if form.validate_on_submit():
user = User()
user.username = form.username.data
user.first = form.first_name.data
user.last = form.last_name.data
user.city = form.city.data
user.dob = form.dob.data
user.gender = form.gender.data
user.home_box = form.home_box.data
user.state = form.state.data
user.street_addr1 = form.street_addr1.data
user.street_addr2 = form.street_addr2.data
user.zip = form.zip.data
user.password = form.password.data
db.session.add(user)
db.session.commit
Right now, inserts are failing because the id is not set:
sqlalchemy.exc.IntegrityError: (IntegrityError) constraint failed 'INSERT INTO users (first, last, dob, street_addr1, street_addr2, city, state, zip, gender, home_box, username, password_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' ('Nate', 'Reed', '1980-11-11', '', '', '', '', '', 'male', '', 'natereed', 'pbkdf2:sha1:1000$N8JHXEDU$24a7724ae9edda81a73e6b92d23aa576ad8284aa')
How do I make id autoincrement? My understanding is it has to be done at the table (not column) level. How do I do this in the code above?

I figured out the problem was I was trying to insert a value for gender that is not valid. It's an enum with values 'M' or 'F'.
It would be nice if the form could just be generated from the model, as that would eliminate the potential for this error. Any pointers on doing that with Flask?

Related

"TypeError: NoneType is not subscriptable" when executing multiple queries

Member function that retrieves db.
def GetDb(self):
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(self.path)
db.row_factory = sqlite3.Row
return db
Member function that returns list from db queries
def GetOrderItemsList(self, orderid):
list = []
with app.app_context():
db = self.GetDb()
cur = db.execute('SELECT * FROM ordersList WHERE orderId = ?',[orderid])
records = cur.fetchall();
for row in records:
print(row)
invid = row['inventoryId']
OrderItem
OrderItem.orderId = row['orderId']
OrderItem.productId = row['inventoryId']
OrderItem.productName = 'none'
OrderItem.quantity = row['quantity']
OrderItem.productPrice = row['price']
nextcur = db.execute('SELECT * FROM inventory WHERE invId = ?', [invid])
#nextcur = db.execute('SELECT * FROM inventory WHERE invId = 1') #works
res = nextcur.fetchone();
OrderItem.productName = res['invName']
print(res['invName'])
list.append(OrderItem)
return list
OrderItem:
class OrderItem(object):
def __init__(self, ordId, invId, name, quantity, price):
self.orderId = ordId
self.productId = invId
self.productName = name
self.quantity = quantity
self.productPrice = price
Error message:
Traceback error
OrderItem.productName = res['invName']
TypeError: 'NoneType' object is not subscriptable
Error
nextcur = db.execute('SELECT * FROM inventory WHERE invId = ?', [invid])
Works
nextcur = db.execute('SELECT * FROM inventory WHERE invId = 1')
Been fighting this for many hours. Searching on google. Reading questions on here.
Any help would be appreciated.
The error
'NoneType' object is not subscriptable
Means that you're trying to access an object's key of an object that doesn't exist, i.e. the object is None.
Please check that here
[invid]
invid is not None, i.e. print (invid)
Also, the issue could be that here
res['invName']
res is None, please check the contents of res (with print, etc) before accessing invName, as it is None.
Fix with join, item instances and img for order product list.
Inventory and OrderItems
create table inventory(invId integer PRIMARY KEY AUTOINCREMENT NOT NULL, invName varchar(50), description varchar(100), invImg varchar(50) ,category integer ,quantity integer, price real);
create table ordersList(orderId integer, inventoryId integer, orderQuantity integer, orderPrice real);
class OrderItem(object):
def __init__(self, ordId, invId, img, name, quantity, price):
self.orderId = ordId
self.productId = invId
self.productName = name
self.productImg = img
self.quantity = quantity
self.productPrice = price
def GetOrderItemsList(orderid):
list = []
db = get_db()
cur = db.execute('SELECT orderId, inventoryId, orderQuantity, orderPrice,
inventory.invName AS invName, inventory.invImg AS invImg FROM ordersList INNERJOIN
inventory ON inventory.invId= ordersList.inventoryId WHERE orderId = ?', [orderid])
records = cur.fetchall();
for row in records:
item = OrderItem(row['orderId'], row['inventoryId'],
row['invImg'], row['invName'],
row['orderQuantity'], row['orderPrice'] )
list.append(item)
return list

Unable to assing IDs automatically in SQLite

I have the following database model:
class Survey(db.Model):
id = db.Column(db.Integer, primary_key=True)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
question_ts = db.relationship('Questions')
class Questions(db.Model):
id = db.Column(db.Integer, primary_key=True)
survey_id = db.Column(db.Integer, db.ForeignKey('survey.id'), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
lan_code = db.Column(db.String(3), nullable=False)
q1 = db.Column(db.String(100), nullable=False)
q2 = db.Column(db.String(100), nullable=False)
q3 = db.Column(db.String(100), nullable=False)
When I insert q1, q2, q3, it fails with a NOT Null constraint failed
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: questions.survey_id
[SQL: INSERT INTO questions (survey_id, date_posted, lan_code, q1, q2, q3) VALUES (?, ?, ?, ?, ?, ?)]
[parameters: (None, '2021-10-06 19:36:08.192194', 'en', 'how are you?', 'Did you get vaccinated?', 'When is your birthday?')]
It works perfectly if I assign IDs manually for the survey. However, is there a way to make the database handle this?
If you are creating a new Survey, you would do it like this:
qs = Questions(q1='Why?', q2='What?', q3='When?')
survey = Survey(question_ts=[qs])
db.session.add(survey)
db.session.commit()
SQLAlchemy will recognise that the objects are related and set up the keys and relationship.
If you are adding a Questions to an existing Survey you append to the relationship:
survey = session.query(Survey).first()
qs = Questions(q1='Why?', q2='What?', q3='When?')
survey.question_ts.append(qs)
db.session.commit()
If you need to obtain ids before committing, add the object(s) to the session and then call the session's flush method.

FLASK-ADDING DATETIME CALCULATION INTO DATABASE

I m trying to perform a little calculation and Logic on date.time with Flask application.
1.) the application will calculate the difference between issue date and expiry date called "remaining days" , The application will check if remaining days is less than 365 days and trigger a function
I attempted the first logic to manipulate the data and submit to database
`#bp.route('/cerpacs/add', methods=['GET', 'POST'])
#login_required
def add_cerpac():
"""
Add a an Cerpac/ expartriates to the database
"""
check_admin()
add_cerpac = True
form =CerpacForm()
if form.validate_on_submit():
cerpac = Cerpac(cerpac_serial_no=form.cerpac_serial_no.data,
cerpac_issue_date= form.cerpac_issue_date.data,
cerpac_exp_date=form.cerpac_exp_date.data,
employee =form.employee.data, )
form.cerpac_issue_date.data = cerpac.cerpac_issue_date
form.cerpac_exp_date.data = cerpac.cerpac_exp_date
if request.method == 'POST':
todays_date = datetime.now()
t = cerpac.cerpac_issue_date
t1 = cerpac.cerpac_exp_date
remaining_days = t1 - t
print(remaining_days) - good prints my result!
remaining_days = cerpac.remaining_days ----not adding to database
try:
add cerpac to the database
db.session.add(cerpac)
db.session.commit()
flash('You have successfully added a Cerpac.' )`
`
my model:
class Cerpac(db.Model):
__tablename__ = 'cerpacs'
id = db.Column(db.Integer, primary_key=True)
cerpac_issue_date = db.Column(db.DateTime)
cerpac_exp_date=db.Column(db.DateTime)
remaining_days = db.Column(db.DateTime)
cerpac_serial_no = db.Column(db.String(60))
cerpac_upload = db.Column(db.String(20), default='cerpac.jpg')
renew_status = db.Column(db.Boolean, default=False)
process_status = db.Column(db.Boolean, default=False)
renewcerpac_id = db.Column(db.Integer, db.ForeignKey('renewcerpacs.id'))
employee_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
def __repr__(self):
return '<Cerpac {}>'.format(self.name) model:
I want to add this to database and eventually write a function like this:
I had a mistake also in the code because I had error issue_date not defined. How do I define issue_date as a date.time variable?
def remaining_days(issue_date, expired_date):
issue_date = datetime(issue_date)
days_to_go = expired - issue
if days_to_go == 365:
renew_status== True
print("time to renew")
print("We are Ok")
I would simplify this to something like:
from datetime import datetime
class Cerpac(db.Model):
...
cerpac_exp_date=db.Column(db.DateTime)
...
#property
def remaining_days(self):
return (self.cerpac_exp_date - self.cerpac_issue_date).days
#property
def days_to_expiry(self):
return (self.cerpac_exp_date - datetime.now()).days
Then, days_to_expiry and remaining_days become properties calculated when you query, and update automatically when they renew their cards.

How can I write two update queries in single stored procedure in SQL Server 2008

I have a table that contains a few columns bound to a gridview.
In that gridview, I have an edit option to update the columns. In that situation I need to write a two update stored procedures that means I select all columns expect AudiotoName, select another columns all columns are update to raise one update query but when I select table in that have AudiotoName column that only edit to select that column it will raise second update stored procedure. I tried but it not properly working can anyone help me out.
My code:
ALTER PROCEDURE up_file
(#ModuleID int,
#SubjectID int,
#Physician varchar(500) = '',
#AuditoName varchar(300) = '',
#AuditoType varchar(50) = '',
#AudioPath varchar(2000) = '',
#BaseDocumentName varchar(500) = '',
#BaseDocumentPath varchar(2000) = '',
#Createddate datetime,
#CreatedBy varchar(200) = '')
AS
BEGIN
IF #AuditoName = 'true' //select AuditoName column only raise this update query
BEGIN
UPDATE SubjectItems
SET ModuleID = #ModuleID,
SubjectID = #SubjectID,
Physician = '#Physician',
AuditoName = '#AuditoName',
AuditoType = '#AuditoType',
AudioPath ='#AudioPath',
BaseDocumentName = '#BaseDocumentName',
BaseDocumentPath = '#BaseDocumentPath'
WHERE AuditoName = #AuditoName
END
BEGIN //normal fields select raise this update query
UPDATE SubjectItems
SET ModuleID = #ModuleID,
SubjectID = #SubjectID,
Physician = '#Physician',
AuditoName = '#AuditoName',
AuditoType = '#AuditoType',
AudioPath ='#AudioPath',
BaseDocumentName = '#BaseDocumentName',
BaseDocumentPath = '#BaseDocumentPath'
WHERE ModuleID = #ModuleID
END
END
Can anyone help me out?
The problem in your query is that, even if #AuditoName is true, the lower update query is running. This will re-update the table SubjectItems. You can use if...else block instead, like below:
ALTER PROCEDURE up_file
(#ModuleID int,
#SubjectID int,
#Physician varchar(500) = '',
#AuditoName varchar(300) = '',
#AuditoType varchar(50) = '',
#AudioPath varchar(2000) = '',
#BaseDocumentName varchar(500) = '',
#BaseDocumentPath varchar(2000) = '',
#Createddate datetime,
#CreatedBy varchar(200) = '')
AS
BEGIN
IF #AuditoName = 'true' //select AuditoName column only raise this update query
BEGIN
UPDATE SubjectItems
SET ModuleID = #ModuleID,
SubjectID = #SubjectID,
Physician = '#Physician',
AuditoName = '#AuditoName',
AuditoType = '#AuditoType',
AudioPath ='#AudioPath',
BaseDocumentName = '#BaseDocumentName',
BaseDocumentPath = '#BaseDocumentPath'
WHERE AuditoName = #AuditoName
END
ELSE
BEGIN //normal fields select raise this update query
UPDATE SubjectItems
SET ModuleID = #ModuleID,
SubjectID = #SubjectID,
Physician = '#Physician',
AuditoName = '#AuditoName',
AuditoType = '#AuditoType',
AudioPath ='#AudioPath',
BaseDocumentName = '#BaseDocumentName',
BaseDocumentPath = '#BaseDocumentPath'
WHERE ModuleID = #ModuleID
END
END

getting Sqlite InterfaceError

hi i am very new to python so please help even if you feel i am asking a silly doubt. the thing is i am creating five lineedits from which values have to be extracted on click of button. but the problem is on click of button i am getting interfaceerror:Error binding parameter 0 - probably unsupported type. Below is my code:
class NewWindow(QtGui.QDialog):
def __init__(self, parent=None):
super(NewWindow, self).__init__(parent)
self.group1= QtGui.QGroupBox("Add Data")
self.patientName = QtGui.QLabel("Name")
self.patientEdit = QtGui.QLineEdit()
self.patientid = QtGui.QLabel("Id")
self.patientidEdit = QtGui.QLineEdit()
self.patientidEdit.setValidator(QtGui.QIntValidator(self.patientidEdit))
self.age = QtGui.QLabel("Age")
self.ageEdit = QtGui.QLineEdit()
self.ageEdit.setValidator(QtGui.QIntValidator(self.ageEdit))
self.genderlabel = QtGui.QLabel("Gender")
self.patientgend = QtGui.QLineEdit()
self.eyeType = QtGui.QLabel("Eye Type")
self.eyeTypeEdit = QtGui.QLineEdit()
self.AddData = QtGui.QPushButton("Add Data")
self.AddData.clicked.connect(self.AddData_clicked)
self.databaseLayout = QtGui.QGridLayout()
self.databaseLayout.addWidget(self.patientName,0,0)
self.databaseLayout.addWidget(self.patientEdit,0,1)
self.databaseLayout.addWidget(self.patientid,2,0)
self.databaseLayout.addWidget(self.patientidEdit,2,1)
self.databaseLayout.addWidget(self.age,4,0)
self.databaseLayout.addWidget(self.ageEdit,4,1)
self.databaseLayout.addWidget(self.genderlabel,6,0)
self.databaseLayout.addWidget(self.patientgend,6,1)
self.databaseLayout.addWidget(self.eyeType,8,0)
self.databaseLayout.addWidget(self.eyeTypeEdit,8,1)
self.databaseLayout.addWidget(self.AddData,10,10)
self.group1.setLayout(self.databaseLayout)
mainLayout = QtGui.QVBoxLayout()
mainLayout.addWidget(self.group1)
mainLayout.addStretch(1)
self.setLayout(mainLayout)
def AddData_clicked(self):
self.db_con = sqlite3.Connection
self.db_name = "./patientData.db"
self.createDb = sqlite3.connect(self.db_name)
self.queryCurs = self.createDb.cursor()
self.name = self.patientEdit.text()
self.id = self.patientidEdit.text()
self.age = self.ageEdit.text()
self.gender = self.patientgend.text()
self.eye_type = self.eyeTypeEdit.text()
self.queryCurs.execute('''CREATE TABLE IF NOT EXISTS PATIENT
(NAME TEXT NOT NULL, ID INTEGER PRIMARY KEY, AGE INTEGER NOT NULL, GENDER TEXT NOT NULL, EYE_TYPE TEXT NOT NULL)''')
self.queryCurs.execute('''INSERT INTO PATIENT(NAME, ID, AGE, GENDER, EYE_TYPE)
VALUES(?,?,?,?,?)''',(self.name,self.id,self.age,self.gender,self.eye_type))
print ('inserted row')
please help me, where am i going wrong........
i am getting error at line VALUES(?,?,?,?,?).......

Resources