SqlAlchemy Relationship on Joined Inheritance fields Results in "where false" SELECT Statement - python-3.x

If I have a shipment with a relationship shipment_legs, I expect that I can call
shipment.shipment_legs to gather all the legs from across the various tables. But the SQL Statement that I see when looking at the echo has an "AND false" appended to it
SELECT *
FROM container_shipment_leg
LEFT OUTER JOIN container_ocean_leg ON container_shipment_leg.id = container_ocean_leg.id
LEFT OUTER JOIN container_road_leg ON container_shipment_leg.id = container_road_leg.id
LEFT OUTER JOIN container_rail_leg ON container_shipment_leg.id = container_rail_leg.id
WHERE container_shipment_leg.shipment_id IN (3) AND false
# Models
class ContainerShipmentLeg(IDomainModel, ABC):
_leg_class: LegClass
sequence: int
def __init__(self, class_type: LegClass, sequence: int):
self._leg_class = class_type
self.sequence = sequence
#hybrid_property
def class_type(self):
raise NotImplementedError("Class Type must be implemented by Subclasses")
class ContainerOceanLeg(ContainerShipmentLeg):
vessel_name: str
voyage_number: str
#hybrid_property
def class_type(self):
return LegClass.SEA
def __init__(self, sequence: int):
super().__init__(self.class_type, sequence)
class ContainerRoadLeg(ContainerShipmentLeg):
reservation_id: str
#hybrid_property
def class_type(self):
return LegClass.ROAD
def __init__(self, sequence: int):
super().__init__(self.class_type, sequence)
class ContainerRailLeg(ContainerShipmentLeg):
pickup_number: str
#hybrid_property
def class_type(self):
return LegClass.RAIL
def __init__(self, sequence: int):
super().__init__(self.class_type, sequence)
# Table
container_shipment_leg_table = Table(
"container_shipment_leg",
metadata,
Column("id", BIGINT, autoincrement=True, primary_key=True, key="id"),
Column(
"shipment_id",
BIGINT,
ForeignKey("shipment.id", link_to_name=True),
key="shipment_id",
index=True,
),
Column("leg_class", Enum(LegClass), key="_leg_class", nullable=False, index=True),
Column("sequence", INT, key="sequence", nullable=False),
)
container_ocean_leg_table = Table(
"container_ocean_leg",
metadata,
Column("id", BIGINT, ForeignKey("container_shipment_leg.id", link_to_name=True), key="id", primary_key=True),
Column("vessel", VARCHAR(50), key="vessel_name"),
Column("voyage_number", VARCHAR(50), key="voyage_number"),
)
container_road_leg_table = Table(
"container_road_leg",
metadata,
Column("id", BIGINT, ForeignKey("container_shipment_leg.id", link_to_name=True), key="id", primary_key=True),
Column("reservation_id", VARCHAR(30), key="reservation_id"),
)
container_rail_leg_table = Table(
"container_rail_leg",
metadata,
Column("id", BIGINT, ForeignKey("container_shipment_leg.id", link_to_name=True), key="id", primary_key=True),
Column("pickup_number", VARCHAR(30), key="pickup_number"),
)
# Mappers
mapper(
ContainerShipmentLeg,
container_shipment_leg_table,
polymorphic_on=container_shipment_leg_table.c._leg_class,
with_polymorphic="*",
)
mapper(
ContainerOceanLeg,
container_ocean_leg_table,
inherits=ContainerShipmentLeg,
polymorphic_load="inline",
polymorphic_identity=LegClass.SEA,
)
mapper(
ContainerRoadLeg,
container_road_leg_table,
inherits=ContainerShipmentLeg,
polymorphic_load="inline",
polymorphic_identity=LegClass.ROAD,
)
mapper(
ContainerRailLeg,
container_rail_leg_table,
inherits=ContainerShipmentLeg,
polymorphic_load="inline",
polymorphic_identity=LegClass.RAIL,
)
mapper(
Shipment,
shipment_table,
properties={
"shipment_legs": relationship(
ContainerShipmentLeg,
lazy=BULK,
single_parent=True,
backref="shipment",
)
},
)
I could use some help figuring out where the "And false" is coming from. INSERTING via the relationship seems to work fine

Related

Index a relationship in SQLAlchemy and Almbic

I have two tables like bellow:
Table 1:
class Table1(Base):
__tablename__ = "table1"
id = Column(UUID, primary_key=True)
created_at = Column(DateTime(True), nullable=False, server_default=func.now())
status_id = Column(ForeignKey("lookups.id"), index=True)
status = relationship(
"Lookup",
primaryjoin="Tables.status_id == Lookup.id",
backref="table1_statuses",
)
Table 2:
class Lookup(Base):
__tablename__ = "lookups"
id = Column(UUID, primary_key=True)
type = Column(String(64))
value = Column(String(256))
maximum = Column(Float(53), server_default="0")
sys_period = Column(TSTZRANGE, nullable=False, index=True)
HOW CAN I do a full text search on Table1 and find the status value. My query will look like this:
model = Table1
# search_term is `value` in the Lookup table
result = (session.query(model)
.filter(model.__ts_vector__.match(search_term)).all)

How to rename keys in response from database by pydantic schema - FastAPI

I have a model from my database in models.py:
class Something(Base):
__tablename__ = "something"
DATE = Column(Date, primary_key=True, index=True )
a = Column(String, primary_key=True, index=True)
b = Column(Integer, primary_key=True, index=True)
c = Column(Float, index=True)
d = Column(Integer, index=True)
e = Column(Integer, index=True)
f = Column(Float, index=True)
g = Column(Float, index=True)
h = Column(Integer, index=True)
and a pydantic model in schema.py:
class Something(BaseModel):
DATE: date
a: str
b: int
c: float = None
d: int = None
e: int = None
f: float = None
g: float = None
h: int = None
class Config:
orm_mode = True
I get data from the database which go through the ORM and in app.get() I declare the response model equal to List[schema.Something], but I want to change the names from the database a, b, c, d to more beautiful names.
Is there a solution like mapping names in NestJS?
Try to use aliases, this is what option allow_population_by_field_name allows to do, for example:
class Person(BaseModel):
first_name: str = Field(..., alias='first')
last_name: str = Field(..., alias='second')
class Config:
allow_population_by_field_name = True
p = Person(**{'first': 'John', 'second': 'White'})
print(p.__dict__)
# {'first_name': 'John', 'last_name': 'White'}

SQLalchemy query not updating relationship columns in put api

I have a model.py with a class Histogram and a table histogram_axes -
histograms_axes = Table(
"histograms_axes",
_ORMBase.metadata,
Column("histogram_id", ForeignKey("histograms.id"), primary_key=True),
Column("axis_id", ForeignKey("axes.id"), primary_key=True),
)
class Histogram(Base):
block = Column(Integer)
num = Column(Integer)
id = Column(Integer, ForeignKey("s.id"))
axes = relationship(
"Axis", secondary=histograms_axes, backref="histograms", order_by="asc(Axis.name)"
)
I have written a put API in FastAPI to update the rows based on id, but it only updates the columns not the relationship in Histogram class.
#router.put("/histograms")
def put_histograms(response: HistogramSchema, id: int, axes: List[int], db: Session = Depends(get_db)):
histogram = db.query(Histogram).filter(Histogram.id == id)
if not histogram.first():
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Histogram id {id} is not found!")
histogram.axes = db.query(Axis).filter(Axis.id.in_(axes)).all()
response = response.dict(exclude_unset=True)
histogram.update(response)
db.commit()
return histogram.one_or_none()
How can I update the relationship table as well.

Python Variable keeps resetting using actions.py

I guys. I have made an actions.py file with several classes. What Im trying to do is that I want a variable (in this case its called flag) I want to set it at zero as default and change it through the function. For some reason it keeps resetting flag to 0 when flag is used in another function.
`
from typing import Any, Text, Dict, List
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
# Import the getData module to fetch the data.
from dbConnect import getData
import dbConnect
import mysql.connector
flag = 0
class FindByLocation(Action):
def name(self) -> Text:
return "action_find_by_location"
def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
location = tracker.get_slot("location")
price= tracker.get_slot("price")
cuisine = tracker.get_slot("cuisine")
print(location)
# write the sql query here.
query = "SELECT Name FROM Restaurant WHERE Location = '%s'" % location
query3 = "SELECT COUNT(Name) FROM Restaurant WHERE Location = '%s' LIMIT 5" % location
query2 = "CREATE VIEW LocationView AS SELECT RestaurantID, Name, PhoneNumber, Rating, PriceRange, Location, Sublocation FROM Restaurant WHERE Sublocation = '%s'"%(location)
#pass the sql query to the getData method and store the results in `data` variable.
var_location = getData(query)
print(var_location)
if not var_location:
flag = 1
var_sublocation = getData(query2)
dispatcher.utter_message(text="یہ جگہ کس ایریا میں ہے")
else:
if cuisine is not None:
count = getData(query3)
dispatcher.utter_message(text="Find By Location",json_message=var_location)
dispatcher.utter_message(text="Results found",json_message=count)
dispatcher.utter_message(text="آپ کس پرائس میں کھانا پسند کریں گے")
else:
count = getData(query3)
dispatcher.utter_message(text="Find By Location",json_message=var_location)
dispatcher.utter_message(text="Results found",json_message=count)
dispatcher.utter_message(text="آپ کس طرح کا کھانا پسند کریں گے؟")
return[]
class FindBySublocation(Action):
def name(self) -> Text:
return "action_find_by_sublocation"
def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
flag = 1
print("FLAG VALUEEEEEE")
print(flag)
location = tracker.get_slot("location")
query = "SELECT Name, Rating FROM LocationView WHERE Location = '%s'" % (location)
query2 = "SELECT COUNT(Name), Rating FROM LocationView WHERE Location = '%s'" % (location)
location = getData(query)
location_count = getData(query2)
dispatcher.utter_message(text="Sublocation Restaurants Found",json_message=location)
dispatcher.utter_message(text="Results found",json_message=location_count)
dispatcher.utter_message(text="آپ کس طرح کا کھانا پسند کریں گے؟")
return[]
class FindByCuisineAndLocation(Action):
def name(self) -> Text:
return "action_find_by_location_and_cuisine"
def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
cuisine = tracker.get_slot("cuisine")
location = tracker.get_slot("location")
print(cuisine)
print(location)
print("flag value in Cuisine and Location")
print(flag)
# write the sql query here.
if flag==0:
query = "Select Name, Rating From Restaurant Where Location = '%s' AND RestaurantID IN (SELECT RestaurantID FROM Cuisine WHERE Name = '%s') LIMIT 5" % (location,cuisine)
query2 = "Select COUNT(Name), Rating From Restaurant Where Location = '%s' AND RestaurantID IN (SELECT RestaurantID FROM Cuisine WHERE Name = '%s') LIMIT 5" % (location,cuisine)
else:
query = "Select Name, Rating From LocationView Where Location = '%s' AND RestaurantID IN (SELECT RestaurantID FROM Cuisine WHERE Name = '%s') LIMIT 5" % (location,cuisine)
query2 = "Select COUNT(Name), Rating From LocationView Where Location = '%s' AND RestaurantID IN (SELECT RestaurantID FROM Cuisine WHERE Name = '%s') LIMIT 5" % (location,cuisine)
#pass the sql query to the getData method and store the results in `data` variable.
location_cuisine = getData(query)
location_cuisine_count= getData(query2)
print("data: ",location_cuisine)
dispatcher.utter_message(text="Find By Cuisine And Location ",json_message=location_cuisine)
dispatcher.utter_message(text="Number of places ",json_message=location_cuisine_count)
dispatcher.utter_message(text="آپ کس پرائس میں کھانا پسند کریں گے")
return []
By the time my flag which should be changed to 1 after being executed in Sublocation (which it does according to the terminal) it is changed to 0 when used again in any other function especially find_by_location_and_cuisine
Thank you for your help!
If you want to use the global flag, use
global flag
in the function you want to use it.
If you don’t mention this statement, the flag variable is considered as a local variable, i.e., a new local variable is created.

SQLAlchemy Order joined table by field in another joined table

My project requires that Orders are split into their individual lines which can be displayed in their own views I want these views to order the lines by eta which is a value in the Order table.
I have 3 tables with a 1>1 join on tables 1&2 and a many>many join on tables 2 and 3 defined by table 4 as follows:
class Order(db.Model):
id = db.Column(db.Integer, primary_key=True)
eta = db.Column(db.DateTime())
order_lines = db.relationship('Line', backref='order', order_by=lambda: Line.id)
def __repr__(self):
return '<Order No. {}>'.format(self.increment_id)
class Line(db.Model):
id = db.Column(db.Integer, primary_key=True)
line_name = db.Column(db.String())
order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
product_id = db.Column(db.String, db.ForeignKey('product.product_id'))
def __repr__(self):
return '<Line SKU: {}>'.format(self.line_sku)
class Line_view(db.Model):
id = db.Column(db.Integer, primary_key=True)
view_name = db.Column(db.String())
view_lines = relationship('Line',
secondary='line_view_join',
backref='views',
lazy='dynamic',
order_by= ***???*** ) #ordery by eta on Order table
def __repr__(self):
return '<View: {}>'.format(self.view_name)
class Line_view_join(db.Model):
__tablename__ = 'line_view_join'
id = db.Column(db.Integer(), primary_key=True)
line_id = db.Column(db.Integer(), db.ForeignKey('line.id', ondelete='CASCADE'))
view_id = db.Column(db.Integer(), db.ForeignKey('line_view.id', ondelete='CASCADE'))
I am trying to work out how to query table 3, Line_View and have the joined Lines ordered by the eta of Order table.
Such that when querying:
chosen_view = Line_view.query.filter_by(id = 1).one()
chosen_view.view_lines are ordered by Order.eta
I have Tried
class Line_view(db.Model):
id = db.Column(db.Integer, primary_key=True)
view_name = db.Column(db.String())
view_lines = relationship('Line',
secondary='line_view_join',
backref='views',
lazy='dynamic',
**order_by=lambda: asc(Line.order.eta))**
def __repr__(self):
return '<View: {}>'.format(self.view_name)
But this results in the error:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Line.order has an attribute 'eta'
Do you need to store the Line_views in the database? If not, you can query the Lines sorted by the eta attribute of the related order. Below, I create two orders with one line each, and then query the lines sorted by the eta attribute of their order:
eta = datetime(2019,10,10)
o = Order(eta = eta)
l = Line(order=o, line_name="sample")
db.session.add(o)
db.session.add(l)
eta = datetime(2019,11,11)
o1 = Order(eta = eta)
l1 = Line(order=o1, line_name="sample1")
db.session.add(o1)
db.session.add(l1)
db.session.commit()
lines = Line.query.join(Order).order_by(Order.eta)

Resources