Saving object creation datetime using Pynamodb - amazon-dynamodb

I want to update the creation_datetime only when a new object is created and update the last_update_datetime on every update while using the save method. default_for_new is updating time even when the existing object is updating. any alternatives?
below is the sample code I tried
from pynamodb.models import Model
from pynamodb.attributes import UTCDateTimeAttribute
def current_datetime():
from datetime import datetime
return datetime.now()
class AbstractDateTimeModel(Model):
creation_datetime = UTCDateTimeAttribute(default_for_new=current_datetime)
last_update_datetime = UTCDateTimeAttribute(default=current_datetime)
class Meta(object):
abstract = True

The best way you can do this is overriding the update method of your Object class. This is an example:
from datetime import datetime, timezone
from pynamodb.models import Model
from pynamodb.settings import OperationSettings
from pynamodb.attributes import UTCDateTimeAttribute, UnicodeAttribute, NumberAttribute
def get_current_time_utc():
return datetime.now(timezone.utc)
class SalesItem(Model):
class Meta:
table_name = 'monthlySales'
id = UnicodeAttribute(hash_key=True)
month= UnicodeAttribute()
sales= NumberAttribute()
createDateTime = UTCDateTimeAttribute(default_for_new=get_current_time_utc)
updateDateTime = UTCDateTimeAttribute(default_for_new=get_current_time_utc)
# overriding the method to add timestamp on update
def update(self, actions=[], condition=None, settings=OperationSettings.default):
actions.append(SalesItem.updateDateTime.set(get_current_time_utc()))
Model.update(self, actions, condition, settings)
We just need to append an action to the actions list asking the timestamp update. Then call the parent's update method. Now you can forget about the timestamps and use the update method as you would.
item = SalesItem.get('pynamodb-test')
# do your updates here
item.update(actions=[
SalesItem.sales.set(item.sales + 1)
])

Related

Tortoise pydantic_model_creator method not contain ForeignKeyField of a model

I have two models Article and Tag. Article has a foreign key from Tag
class Tag(MyAbstractBaseModel):
name = fields.CharField(max_length=255, index=True)
class Article(MyAbstractBaseModel):
title = fields.CharField(max_length=255, index=True)
body = fields.CharField(max_length=255)
tag = fields.ForeignKeyField(model_name="Tag", related_name='article', on_delete=fields.CASCADE)
Here I would like to have my response checked by the following
#router.get("/article", response_model=get_serialize_pydantic(Article))
async def get():
pass
Here is how I get the response model
from tortoise.contrib.pydantic import pydantic_model_creator
from pydantic import BaseModel, Field, create_model
def get_serialize_pydantic(models_obj: Type[Model], exclude: Tuple[str, ...] = None):
my_model_pydantic = pydantic_model_creator(models_obj)
response_pydantic = create_model(
__model_name=f"{models_obj.__name__}_response_pydantic",
data=(Optional[List[my_model_pydantic]], Field(None, title="data")),
__base__=BaseResponse)
return response_pydantic
Problem is I only title and body in my response model, there is no tag in it. Anyone knows why?
This is not an issue from pydantic side. It's pydantic_model_creator of tortoise that causes the problem.
The solution is simple. Just init before serialisation.
from tortoise import Tortoise
Tortoise.init_models(["__main__"], "models")
my_model_pydantic = pydantic_model_creator(models_obj)
https://tortoise-orm.readthedocs.io/en/latest/contrib/pydantic.html#relations-early-init

Qt Designer/PyQt/Python how to access an element?

Please help. There is a layout ui file. I connected it - I did several manipulations through the Form class. Now I want to create a class with layout change. But I don’t understand how to “reach out” to the element .... I am attaching the code, the ui file too
Converting to py file does not make sense in my case. I ask for help - tell me how can I create a class with what I have and change the elements?
File ui
https://github.com/Anzhelika007/PyQt6_app/blob/master/interface.ui
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
import sqlite3
Form, Window = uic.loadUiType('interface.ui')
app = QApplication([sys.argv])
window = Window()
form = Form()
form.setupUi(window)
window.show()
# so it works, but I want to understand - how can I create a class correctly
# form.label_11.setText('erthtzrjnsymzgs')
class UI(QMainWindow, Form):
def __init__(self):
super(UI, Form, self).__init__()
self.setupUi(self)
self.label_11.setText('erthtzrjnsymzgs') # this does not work
self.tableWidget.setColumnWidth(0, 50) # this does not work
self.tableWidget.setColumnWidth(1, 100) # this does not work
self.tableWidget.setColumnWidth(2, 150) # this does not work
self.tableWidget.setColumnWidth(3, 200) # this does not work
def registration():
user_login = form.userName.text()
user_email = form.email.text()
user_phone = form.phoneNamber.text()
user_value = (user_login, user_email, user_phone)
try:
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute("INSERT INTO users(Username, Email, PhoneNumber) VALUES (?,?,?)", user_value)
conn.commit()
cursor.execute("SELECT * FROM users")
k = cursor.fetchall()
print(k)
cursor.close()
except Exception as e:
print(e)
print(user_value)
form.addUserBtn.clicked.connect(registration)
sys.exit(app.exec())
# database creation code I have separately
import sqlite3
with sqlite3.connect('database.db') as db:
cursor = db.cursor()
cursor.execute("""CREATE TABLE IF NOT EXISTS users(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
Username VARCHAR(30),
Email VARCHAR(30),
PhoneNumber VARCHAR(15)
)""")
users_x = [('Yanitya', 'geffelleceffe-7860#yopmail.com', '9(3484)364-32-92'),
('Ricahav', 'kajaddunneito-2898#yopmail.com', '5(4119)578-75-50'),
('Corbert', 'tebrijofuyu-9922#yopmail.com', '4(04)160-64-89'),
('Xerxesar', 'houcrukefamu-5882#yopmail.com', '152(238)276-36-46')]
cursor.executemany("INSERT INTO users(Username, Email, PhoneNumber) VALUES (?,?,?)", users_x)
for i in cursor.execute('SELECT * FROM users'):
print(i)

How to define Auto evaluation and attempted multiple times constraint in MCQ for django model?

I am working on a MCQ based django project and based on my research I have below models that I got from 3rd party reference. Of course I had to make some modification based on my custom need. below is the snippet from models.py:
from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
class Quiz(models.Model):
name = models.CharField(max_length=1000)
questions_count = models.IntegerField(default=0)
description = models.CharField(max_length=70)
created = models.DateTimeField(auto_now_add=True,null=True,blank=True)
slug = models.SlugField()
roll_out = models.BooleanField(default=False)
class Meta:
ordering = ['created', ]
verbose_name_plural = 'Quizzes'
def __str__(self):
return self.name
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
label = models.CharField(max_length=1000)
order = models.IntegerField(default=0)
marks = models.IntegerField(default=0)
optional = models.BooleanField(default=False)
def __str__(self):
return self.label
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
text = models.CharField(max_length=1000)
is_correct = models.BooleanField(default=False)
def __str__(self):
return self.text
class QuizTakers(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
correct_answers = models.IntegerField(default=0)
completed = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
class Response(models.Model):
quiztaker = models.ForeignKey(QuizTakers, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer = models.ForeignKey(Answer,on_delete=models.CASCADE,null=True,blank=True)
def __str__(self):
return self.question.label
#receiver(post_save, sender=Quiz)
def set_default_quiz(sender, instance, created, **kwargs):
quiz = Quiz.objects.filter(id=instance.id)
quiz.update(questions_count=instance.question_set.filter(quiz=instance.pk).count())
#receiver(post_save, sender=Question)
def set_default(sender, instance, created, **kwargs):
quiz = Quiz.objects.filter(id=instance.quiz.id)
quiz.update(questions_count=instance.quiz.question_set.filter(quiz=instance.quiz.pk).count())
#receiver(pre_save, sender=Quiz)
def slugify_title(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.name)
However, there are couple of points that I have implement for my MCQs for which I am not able to find proper solution. Below are the points.
1) Every quiz can be attempted multiple times by the quiz taker. No restriction.
2) Since the questions are in MCQ format, the quiz taker answers are auto-evaluated by the application.
Any help would be highly appreciated.
Thank you.
To answer both your questions:
Since every quiz can be done multiple times you will simply have a reset button. Once that button is clicked, it will delete the QuizTaker. You will then be able to create it again.
When you create a quiz all the questions have answers and one of those answers is correct. Therefore, you can define a function that checks if the response provided is equal to the correct answer then increment the number of correct answers by 1 for each correct answer.
I hope this helps!!

how to add data from ui (made using pyqt) to sqlite db?

i have made a simple pyqt gui with QLineEdit and QPushButton. i like to add showurl(in con.py given below) to sqlite db. the code :
ui.py
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(400, 300)
self.verticalLayout_2 = QtGui.QVBoxLayout(Form)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.inserturl = QtGui.QLineEdit(Form)
self.inserturl.setObjectName(_fromUtf8("inserturl"))
self.verticalLayout.addWidget(self.inserturl)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.insertdb_btn = QtGui.QPushButton(Form)
self.insertdb_btn.setObjectName(_fromUtf8("insertdb_btn"))
self.verticalLayout.addWidget(self.insertdb_btn)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
self.insertdb_btn.setText(_translate("Form", "ok", None))
con.py
import sys
from PyQt4 import QtCore, QtGui, QtSql
from insertdb2_ui import Ui_Form
def createConnection():
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('webscrap.db')
if db.open():
return True
else:
print db.lastError().text()
return False
class Test(QtGui.QWidget, Ui_Form):
def __init__(self):
super(Test, self).__init__()
self.setupUi(self)
self.insertdb_btn.clicked.connect(self.onClick)
def onClick(self):
showurl = self.inserturl.text()
print showurl
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
if not createConnection():
sys.exit(1)
window = Test()
window.show()
sys.exit(app.exec_())
i made the input data ie. showurl print on terminal. i want to add the showurl to sqlitedb webscrap.db which has fields id and url.
I am also confused about using model view(QSqlTableModel, QDataWidgetMapper).
You can use the QtSql.QSqlQuery() class to create query objects that interact with your database. To execute a query (in this case, an INSERT query), perform the following steps:
Instantiate a QSqlQuery() object.
Call the prepare() method on that object, passing to the prepare() method the SQL text that you want to execute.
Use the addBindValue() method to pass in variables to your query -- in this case, you want to pass in showurl.
Finally, call exec_() on the query object to execute
the query. If there is an error, you can retrieve it by calling on
the query object lastError().text().
So, in code, you would need to change your onClick() function to:
def onClick(self):
showurl = self.inserturl.text()
query_object = QtSql.QSqlQuery()
query_object.prepare("INSERT INTO table (url) VALUES (?)")
query_object.addBindValue(showurl)
if not query_object.exec_():
print query_object.lastError().text()
Please note that I did not specify a table name to insert into because you provided field names (id and url) but not a table name; therefore the query string uses a fake table name (table). You should replace this with a real table name. If you do not have a table in your database, you need to create one. Please reference https://www.sqlite.org/lang.html for documentation on SQLite commands (e.g. for creating tables). Please also refer to the PyQt4 documentation on QtSql.QSqlQuery(): http://pyqt.sourceforge.net/Docs/PyQt4/qsqlquery.html
For QSqlTableModel and QDataWidgetMapper, it is difficult to help without having a specific question to answer about them, but I highly recommend that you check out this excellent guide to both of those classes: http://doc.qt.digia.com/qq/qq21-datawidgetmapper.html. This guide does not use PyQt4 (instead it uses Qt alone, so the code is in C++), but the code is sparse and the concepts should resonate even if you are not familiar with C++.

Plone 4 related items back reference issue

I failed to find back reference object for related items.
my code:
back_rels = list(catalog.findRelations({'to_id': intids.getId(aq_base(self.context))}))
for rel in back_rels:
ob = portal.unrestrictedTraverse(rel.from_path)
It throws exception when running at ob = portal.unrestrictedTraverse(rel.from_path).
Debug results:
> len(back_rels)
> 1
> rel
> <z3c.relationfield.relation.RelationValue object at oxoA86f8f0>
> rel.from_path
> 'new-grants-target-bioterrorism'
> rel.to_path
> '/portal/urnews/ur-gets-20-million-for-biodefense-studies'
I guess the problem is the rel.from_path doesn't return the full path like the rel.to_path does.
My question is how can rel.from_path return with full path and get right object at
portal.unrestrictedTraverse(rel.from_path)?
I am running Plone 4 and use dexterity content type.
Unfortunately you can't access from_object directy. It is explained in this issue http://code.google.com/p/dexterity/issues/detail?id=95
Use from_id, which stores IntId and use IntIds utility to retrieve the particular object:
from Acquisition import aq_inner
from zope.component import getUtility
from zope.intid.interfaces import IIntIds
from zope.security import checkPermission
from zc.relation.interfaces import ICatalog
def back_references(source_object, attribute_name):
""" Return back references from source object on specified attribute_name """
catalog = getUtility(ICatalog)
intids = getUtility(IIntIds)
result = []
for rel in catalog.findRelations(
dict(to_id=intids.getId(aq_inner(source_object)),
from_attribute=attribute_name)
):
obj = intids.queryObject(rel.from_id)
if obj is not None and checkPermission('zope2.View', obj):
result.append(obj)
return result

Resources