Double Relationship in SQLalchemy - database

I got following problem in sqlalchemy. I made three different tables in sqlite, the first has no realtion, the second has a relation to the first and the third a relation to the second. So when I want to insert things in the first and the second table everything works fine. When I want to insert datas in the third table I'm getting troubles when I'm going to do it like it's discribed in the tutorial. Here is my code for the three tables:
First table:
# Save_Data_Type.py
from sqlalchemy import ForeignKey
from sqlalchemy import Column, Float, Integer, String
from base import Base
from sqlalchemy.orm import relationship, backref
########################################################################
class Save_Data_Type(Base):
__tablename__ = "save_datas_type"
save_datas_type_id = Column(Integer, primary_key=True)
type_memory = Column(String)
comment = Column(String)
dummy1 = Column(String)
dummy2 = Column(String)
#----------------------------------------------------------------------
def __init__(self, type_memory, comment, dummy1, dummy2):
""""""
self.type_memory = type_memory
self.comment = comment
self.dummy1 = dummy1
self.dummy2 = dummy2
Second Table
# Save_Data.py
from sqlalchemy import ForeignKey
from sqlalchemy import Column, Float, Integer, String
from base import Base
from sqlalchemy.orm import relationship, backref
########################################################################
class Save_Data(Base):
""""""
__tablename__ = "save_datas"
save_datas_id = Column(Integer, primary_key=True)
save_datas_type_id = Column(Integer,ForeignKey("save_datas_type.save_datas_type_id"))
save_datas_type = relationship("Save_Data_Type", backref=backref("save_datas", order_by=save_datas_id))
value = Column(Float)
comment = Column(String)
dummy1 = Column(String)
#----------------------------------------------------------------------
def __init__(self, value, comment, dummy1):
""""""
self.value = value
self.comment = comment
self.dummy1 = dummy1
Third Table
# Station.py
from sqlalchemy import ForeignKey
from sqlalchemy import Column, Integer, Boolean, String
from base import Base
from sqlalchemy.orm import relationship, backref
########################################################################
class Station(Base):
""""""
__tablename__ = "stations"
stations_id = Column(Integer, primary_key=True)
name = Column(String)
password = Column(String)
save_datas_id = Column(Integer,ForeignKey("save_datas.save_datas_id"))
save_datas = relationship("Save_Data", backref=backref("stations", order_by=stations_id))
dummy1 = Column(String)
dummy2 = Column(String)
dummy3 = Column(String)
#----------------------------------------------------------------------
def __init__(self, name, password, dummy1, dummy2, dummy3):
""""""
self.name = name
self.password = password
self.dummy1 = dummy1
self.dummy2 = dummy2
self.dummy3 = dummy3
base.py
# base.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
So if I'm going to insert the datas like that:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import base
from Save_Data_Type import Save_Data_Type
from Save_Data import Save_Data
from Station import Station
engine = create_engine('sqlite:///Database.db', echo=True)
base.Base.metadata.create_all(engine, checkfirst=True)
# create a Session
Session = sessionmaker(bind=engine)
session = Session()
jack = Save_Data_Type("Ring Memory",'In seconds',None,None)
jack.save_datas = [Save_Data(1980,'Sometimes more, sometimes less',None)]
jack.save_datas.stations = [Station('name1','123456',None,None,None)]
session.add(jack)
session.commit()
Nothing is writing in the the third table of the database. How is the usual way to build this relationship?
Thanks in advance,
Johannes

Apart from some typos in the code you posted (see comment from zzzeek), it looks like the problem will be solved by replacing the code:
jack.save_datas.stations = [Station('name1','123456',None,None,None)]
with the one below:
jack.save_datas[0].stations = [Station('name1','123456',None,None,None)]
The reason is the following: in your case you assign/create a stations attribute to a class member. Not only this does not do the right job, it might actualy harm your ORM model.
In the second case you correctly assign the Station instance to the first save_datas.
The more clear code would look like this:
jack = Save_Data_Type("Ring Memory",'In seconds',None,None)
save_data1 = Save_Data(1980,'Sometimes more, sometimes less',None)
jack.save_datas.append(save_data1)
# or: jack.save_datas = [save_data1]
# or (my favourite): save_data1.Save_Data_Type = jack
save_data1.stations = [Station('name1','123456',None,None,None)]
# or... similar to the relationship above

Related

Custom Locust User for SageMaker Endpoint Keeps running after time limit is reached

I have been trying to build a SagemakerUser from the base User class in the Locust library. The issue though is when I use it with a timed shape test, when said test ends (you can see a message: Shape test stopping) the load test shrugs it off and continues. Below is the script I have written to this end. My question is how is this behaviour explained?
import pandas as pd
from locust import HttpUser, User, task, TaskSet, events, LoadTestShape
from sagemaker.serializers import JSONSerializer
from sagemaker.session import Session
import sagemaker
import time
import sys
import math
import pdb
df = "some df to load samples from"
endpoint = "sage maker end point name"
class SagemakerClient(sagemaker.predictor.Predictor):
def predictEx(self, data):
start_time = time.time()
start_perf_counter = time.perf_counter()
name = 'predictEx'
try:
result = self.predict(data)
except:
total_time = int((time.perf_counter() - start_perf_counter) * 1000)
events.request_failure.fire(request_type="sagemaker", name=name, response_time=total_time, exception=sys.exc_info(), response_length=0)
else:
total_time = int((time.perf_counter() - start_perf_counter) * 1000)
events.request_success.fire(request_type="sagemaker", name=name, response_time=total_time, response_length=sys.getsizeof(result))
class SagemakerLocust(User):
abstract = True
def __init__(self, *args, **kwargs):
super(SagemakerLocust, self).__init__(*args, **kwargs)
self.client = SagemakerClient(
sagemaker_session = Session(),
endpoint_name = "sagemaker-test",
serializer = JSONSerializer())
class APIUser(SagemakerLocust):
#task
def call(self):
request = df.text.sample(1, weights=df.length).iloc[0]
self.client.predictEx(request)
class StepLoadShape(LoadTestShape):
"""
A step load shape
Keyword arguments:
step_time -- Time between steps
step_load -- User increase amount at each step
spawn_rate -- Users to stop/start per second at every step
time_limit -- Time limit in seconds
"""
step_time = 30#3600
step_load = 1
spawn_rate = 1
time_limit =2#3600*6
#pdb.set_trace()
def tick(self):
run_time = self.get_run_time()
if run_time > self.time_limit:
return None
current_step = math.floor(run_time / self.step_time) + 1
return (current_step * self.step_load, self.spawn_rate)

Flask sqlalchemy, how to avoid circular dependency in this case?

I'v been banging my head over this for 2 days straight and i still can understand/find a way to do this and it looks super simple but im obviously overlooking something (also im fairly new to DBs :) ).
I want to have Owner and Pet model.
Pets have 'owner ids' as foreign keys, and Owners have 'pets' as relationship, so far so good.
But now i also want Owners to have one 'pet id' written as 'favorite pet'.
Having foreign keys in both models (each others keys) started to make bunch of different problems (different depending on how i try to solve it, but either circular dependency or some multipath error)
I also noticed that if i avoid having 'favourite_pet_id'-foreign key in Owner model, keeping only favourite_pet-relationship, then i dont have this written anywhere in DB (at least not visible), it exists only as 'relationship' ?
What would be correct way of doing this ?
Thanks in advance !
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Owner(db.Model):
id = db.Column(db.Integer, primary_key=True)
pets = db.relationship('Pet', foreign_keys='Pet.owner_id')
favourite_id = db.Column(db.Integer, db.ForeignKey('pet.id'))
favourite = db.relationship('Pet', uselist=False, foreign_keys='Owner.favourite_id')
class Pet(db.Model):
id =db.Column(db.Integer, primary_key=True)
owner_id = db.Column(db.Integer, db.ForeignKey('owner.id'))
owner = db.relationship('Owner', uselist=False, back_populates='pets', foreign_keys='Pet.owner_id')
o = Owner() # one owner
p1 = Pet() # pet 1
p2 = Pet() # pet 2
p1.owner=o # setting owner for pet1
p2.owner=o # setting owner for pet2
o.favourite=p2 # setting pet2 to be favourite
#db.session.add(o)
#db.session.add(p1)
#db.session.add(p2)
#db.session.commit()
print (p1.owner) # owner
print (p2.owner) # owner
print (p1) # pet 1
print (p2) # pet 2
print (o.pets) # owners pets
print (o.favourite) # favourite pet
Here's a working version of your code below. The key is being more explicit about the relationship (e.g. join condition) as there are multiple relationships between the models/tables.
Note: While not part of your question/request, I also reformatted a bit for PEP8 conformity and readability. The later is a good practice to adopt early on as model files typically grow quickly and can become very difficult to read, digest, and debug.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Owner(db.Model):
id = db.Column(
db.Integer,
primary_key=True,
)
favourite_pet_id = db.Column(
db.Integer,
db.ForeignKey('pet.id'),
nullable=True,
)
favourite_pet = db.relationship(
'Pet',
uselist=False,
foreign_keys=[favourite_pet_id],
primaryjoin='Pet.owner_id == Owner.favourite_pet_id',
)
class Pet(db.Model):
id = db.Column(
db.Integer,
primary_key=True,
)
owner_id = db.Column(
db.Integer,
db.ForeignKey('owner.id'),
)
owner = db.relationship(
'Owner',
uselist=False,
foreign_keys=[owner_id],
primaryjoin='Pet.owner_id == Owner.id',
backref=db.backref(
'pets',
uselist=True,
),
)
db.create_all()
o = Owner() # one owner
p1 = Pet() # pet 1
p2 = Pet() # pet 2
p1.owner = o # setting owner for pet1
p2.owner = o # setting owner for pet2
o.favourite_pet = p2 # setting pet2 to be favourite
print(p1.owner) # owner
print(p2.owner) # owner
print(p1) # pet 1
print(p2) # pet 2
print(o.pets) # owners pets
print(o.favourite) # favourite pet

how to use initiate function for a cart in Django?

I'm learning Django and I'm trying to make a Cart, which the customer can get and item and add it in his/her order row and then the order will be submitted. so my teacher said use def initiate(customer), and I don't understand how to use it. Can someone please explain it to me? Thank you.
here is the code I'm working on it:
User = get_user_model()
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=Product, related_name="User")
phone = models.CharField(max_length=20)
address = models.TextField()
balance = models.IntegerField(default=20000)
def deposit(self, amount):
self.balance += amount
self.save()
def spend(self, amount):
if amount > self.balance:
raise ValueError
self.balance -= amount
self.save()
class OrderRow(models.Model):
product = models.ManyToManyField(Product)
order = models.ForeignKey('Order', on_delete=models.CASCADE)
amount = models.IntegerField()
class Order(models.Model):
# Status values. DO NOT EDIT
STATUS_SHOPPING = 1
STATUS_SUBMITTED = 2
STATUS_CANCELED = 3
STATUS_SENT = 4
customer = models.ForeignKey('Customer', on_delete=models.SET_NULL)
order_time = models.DateTimeField(auto_now=True)
total_price = Sum(F('amount') * F('product__price'))
status = models.IntegerField(choices=status_choices)
#staticmethod
def initiate(customer):
Order.initiate(User)
def add_product(self, product, amount):
Order.status = 1
OrderRow.product = Product.objects.get(id=product.id)
print(product.id)
if OrderRow.objects.filter(product=product).exists():
preexisting_order = OrderRow.objects.get(product=product, order=self)
preexisting_order.amount += 1
preexisting_order.save()
else:
new_order = OrderRow.objects.create(
product=product,
cart=self,
amount=1,
)
new_order.save()
You are probably supposed to create a new Order associated with this customer. Something along the following lines:
#classmethod
def initiate(cls, customer):
return cls.objects.create(customer=customer, status=cls.STATUS_SHOPPING)
There are some other issues with your code. You cannot use SET_NULL if the fk is not nullable:
customer = models.ForeignKey('Customer', on_delete=models.SET_NULL, null=true)
There should not be multiple products per row:
class OrderRow(models.Model):
product = models.ForeignKey(Product) # not many2many!
# ...
Also, your add_product needs quite some fixing:
def add_product(self, product, amount):
self.status = self.STATUS_SHOPPING # the instance is self + use your descriptive variables
print(product.id)
# filter only rows in the current order!
if self.orderrow_set.filter(product=product).exists():
# fix naming: this is a row, not an order
preexisting_order_row = self.orderrow_set.get(product=product)
preexisting_order_row.amount += amount # why +1, you are adding amount
preexisting_order_row.save()
else:
new_order_row = OrderRow.objects.create(
product=product,
order=self,
amount=amount,
) # create saves already

Displaying SQLite data in a Tkinter GUI

So I have a very simply Tkinter GUI which takes an input parameter and inputs it into a SQLite database. I'm looking to create a secondary GUI which will extract this parameter from the SQLite database and display it on the secondary GUI. Can you please help on how to do this? Preferably I want to display this data from the DB on a text field or something of the like.
from Tkinter import *
from PIL import Image, ImageTk
import sqlite3
root = Tk()
root.wm_attributes('-fullscreen','true')
root.title("My Test GUI")
Fullname=StringVar()
conn = sqlite3.connect('Form.db')
cursor=conn.cursor()
def database():
name1=Fullname.get()
cursor.execute('CREATE TABLE IF NOT EXISTS Student (Fullname TEXT)')
cursor.execute('INSERT INTO Student (FullName) VALUES(?)',(name1,))
conn.commit()
def error():
root1 = Toplevel(root)
root1.geometry("150x90")
root1.title("Warning")
Label(root1, text = "All fields required", fg = "red").pack()
def read_from_db():
cursor.execute('SELECT * FROM Student')
data = cursor.fetchall()
print(data)
label_0 = Label(root, text="My Test GUI",width=20,font=("bold", 20))
label_0.place(x=650,y=53)
label_1 = Label(root, text="Name",width=20,font=("bold", 10))
label_1.place(x=550,y=130)
entry_1 = Entry(root,textvar=Fullname)
entry_1.place(x=700,y=130)
Button(root, text='Submit',width=20,bg='brown',fg='white', command=database).place(x=650,y=380)
root.mainloop()
read_from_db()
Within your read_from_db function, instead of printing the value of data you can make a label out of it:
def read_from_db():
cursor.execute("SELECT *, oid FROM Student")
data = c.fetchall()
showData = ''
for data in Student:
showData += str(data) + "\n"
dataLabel = Label(master, text=showData)
playerLabel.grid(row=0, column=0)
conn.commit()
conn.close()

How I can get difference of queries?

class PostTemplate(BaseModel):
content = TextField(unique=True)
class VkGroup(BaseModel):
group_id = IntegerField(unique=True)
class PostTemplateVkGroup(BaseModel):
"""
http://charlesleifer.com/blog/a-tour-of-tagging-schemas-many-to-many-bitmaps-and-more/
"""
group = ForeignKeyField(VkGroup)
post_template = ForeignKeyField(PostTemplate)
def get_posted_templates_for_group(group_id: int) -> Iterable:
"""Get posted templates.
Args:
group_id (int): id группы
"""
queries = (PostTemplate
.select()
.join(PostTemplateVkGroups)
.join(VkGroup)
.where(VkGroup.group_id == group_id))
return queries
all_post_templates = PostTemplate.select()
Many-to-many relationship.
For every record in PostTemplateVkGroup post template from this record is used in group from this record.
all_post_templates = not_posted_templates | posted_templates
How I can get not_posted_templates?
If your database supports the "EXCEPT" operation, you can:
all_post_templates = PostTemplate.alias().select()
post_templates = get_posted_templates_for_group(...)
difference = all_post_templates - post_templates
Sqlite example:
class Post(Base):
title = TextField()
class Tag(Base):
tag = TextField()
class PostTag(Base):
post = ForeignKeyField(Post)
tag = ForeignKeyField(Tag)
db.create_tables([Post, Tag, PostTag])
data = (
('pa', ('ta1', 'ta2')),
('pb', ('tb1', 'tb2')),
('pc', ()))
for title, tags in data:
post = Post.create(title=title)
for tag in tags:
tag = Tag.create(tag=tag)
PostTag.create(post=post, tag=tag)
# Create some tags that aren't associated with any post.
Tag.create(tag='tx1')
Tag.create(tag='tx2')
pa1_tags = (Tag
.select()
.join(PostTag)
.join(Post)
.where(Post.title == 'pa'))
all_tags = Tag.alias().select()
diff = all_tags - pa1_tags
for t in diff:
print(t.tag)
# Prints
# tb1
# tb2
# tx1
# tx2

Resources