pydantic initialize new object with an existing object (fastapi) - python

I have a Base class, to get the values from the frontend. The user_id should comes from the Depends(deps.get_current_user) function.
How can i initialize the new class CommentCreate now, with the values from CommentBase?
And is this the common use?
I got it worked with the workaround extra=Extra.allow and setattr(message,...)
I think it should be something like: commentCreate = schemas.CommentCreate(**comment, user_id=current_user.id)
class CommentBase(BaseModel, extra=Extra.allow):
blog_id: int
message: str
class CommentCreate(CommentBase):
user_id: int
#router.post("/post/comment")
def post_comment_reply(
message: schemas.CommentBase,
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
):
setattr(message, "user_id", current_user.id)
print(message)

You can use the dict method to achieve this.
something like :
CommentCreate(user_id=current_user , **message.dict())

Related

Problems understanding Pydantic model with metaclasses/ aliases mapping when using SqlAlchemy

I'm trying to have my Pydantic/ORM models "output" labels,but when using SqlAlchemy ORM I feel a bit locked/ stuck.
I want the fieldname "test1" ( below in the code) to return ( "Test left side") instead of test1 in the JSONResponse
As an explanation, In sql i would for example use “as”
select test1 as ‘Test left side’ from pretest
I know I can do the same in an ORM statement/query, but I want it to be reachable as a field/ attribute from the orm model class, or perhaps as some validation methods from my Pydantic model.
To explain I have added an example of two short models below
my model in Sqlalchemy:
class Pretest(Base):
__tablename__ = "pretest"
user_id = Column(Integer)
pretest_id = Column(Integer, primary_key=True)
timestamp_pretest = Column(DateTime(timezone=True), default=func.now())
test1 = Column(Integer)
my model in Pydantic: ( I use Optional because im testing at the moment)
class Pretest(BaseModel):
user_id: Optional[int] = None
pretest_id: Optional[int] = None
timestamp_pretest: Optional[datetime] = None
test1: Optional[int] = None
class Config:
orm_mode= True
So I’m wondering if Pydantic have a possibility to validate against a labelslist/array/ object that could contain a type of test1= “Test left side”
Or if the ORM models have some additional metadata that could be used like
test1 = Column(Integer, alias=“Test left side”)
I hope I make this question understandable?
My endpoint look a bit simplified something like this:
#router.post("/pretest", tags=["Medicaldata"], status_code=status.HTTP_200_OK)
def pretest(pretest: Pretest, token: str = Depends(oauth2_scheme)):
try:
query = db.query(models.Pretest).first()
except:
query = "query failed"
return JSONResponse(content=query)
Where I use the pretest-object which is type defined by the Pydantic model as query parameters( not shown here)
This response will create a json-object of the fields and values in the database.
The field/variable test1 will return as test1 instead of "Test left side", since I do not have a place to add labels or some sort of aliases.
I can add and map the json object manually in Python before I return it, but it’s a lot of complex queries spanning several tables, so it feels a bit “wrong” to do it that way.
The reason for all this is so that I can have model and label consistency and use the map function with spread operators in components in React as shown below.
get_backend(“/pretest”,data)
.then setPretestlist(response)
{pretestlist.map((item) => {
return <ShowPretest {...item} key={item.name} />;
})}
This will now show as test1 in the webpage instead of a more explanatory text like this "Test 1 left side"
#snakecharmerb, Thx, you put me on the right track.
The solution, if someone else wonder:
the Pydantic model needs to be changed from this:
class Pretest(BaseModel):
user_id: Optional[int] = None
pretest_id: Optional[int] = None
timestamp_pretest: Optional[datetime] = None
test1: Optional[int] = None
class Config:
orm_mode = True
To this:
class Pretest(BaseModel):
user_id: Optional[int] = None
pretest_id: Optional[int] = None
timestamp_pretest: Optional[datetime] = None
test1: Optional[int] = None
class Config:
fields = {
"test1": "Test left side",
"timestamp_pretest": "Time tested",
}
orm_mode = True
The endpoint needed to change in the way it does its response to this:
#router.post("/pretest", tags=["Medicaldata"], status_code=status.HTTP_200_OK)
def pretest(pretest: Pretest, token: str = Depends(oauth2_scheme)):
try:
query = db.query(models.Pretest).first()
query = Pretest.from_orm(query)
except:
query = "query failed"
return query.dict(by_alias=True)

Dont see object id that is inside a list of objects beanie odm

I have the following code for the Beanie ODM (for Python):
class PlanetDocument(Document):
created_at: datetime
name: str = "Planet"
class UserDocument(Document):
id: Indexed(str)
username: Optional[str] = None
planets: List[PlanetDocument] = []
class Settings:
name = "user"
When I store a PlanetDocument, I can see it has it's id, but when I store the same planet on the UserDocument planets list the object doesnt has id, I store it in user the following way:
user = await UserDocument.get(planet_data.user)
new_planet = PlanetDocument("time", "name")
new_planet = await new_planet.create()
user.planets.append(new_planet)
await user.save()
Then I lookup user[0].planets[0] and it has not it's id set
This solved my issue:
https://roman-right.github.io/beanie/tutorial/relations/
Instead of using normal typing, I missed to setup relation by using Link.

Increment all fields of all objects in a collection pymongo

Hello i would like to increment the field current_week of all objects in the collection tournaments but i get an error. I have the code:
class DataBase:
def __init__(self):
self.myclient = pymongo.MongoClient("mongodb://localhost:27017/")
self.mydb = self.myclient["MMA_TOURNAMENT"]
self.tournaments = self.mydb["tournaments"]
def insert_new_tournament(self, tournament):
print(tournament.__dict__)
self.tournaments.insert_one(tournament.__dict__)
def increment_day(self):
self.tournaments.update({'$inc': {'current_week' : 1}})
and i get the error:
TypeError: update() missing 1 required positional argument: 'document'
when calling the function. I am a beginner in pymongo I really don't know what query I should put there. Thank you!
You need to pass a filter as the first parameter to update_many(); to update every document your filter is simply {}.
def increment_day(self):
self.tournaments.update_many({}, {'$inc': {'current_week' : 1}})

PonyORM retrieve object from class Entity problem

Let's say I have these two classes:
class TeamMember(db.Entity):
member_id= PrimaryKey(int, auto=True)
name = Required(str)
team = Required('Team')
class Team(db.Entity):
team_id= PrimaryKey(int, auto=True)
name = Required(str)
team_members = Set(TeamMember)
I want to select all TeamMembers that are in specific team (ex. team_id==1). Query would look something like this (C1):
TeamMember.select(lambda member: member.team == 1)[:]
If I write it like that, I'm getting error below:
Incomparable types 'Team' and 'int' in expression: member.team == 1
On the other hand, I can write this and it will work (C2):
TeamMember.select(lambda member: member.team == Team[1])[:]
But, I don't wan't to write it like it, because I want to create generic function that will work for every Entity class:
def get_instances_from_db(classname, classname_var, var_value):
"""
:param classname: name of class
:param classname_var: name of class variable to search by
:param var_value: value of class variable
:return:
"""
return classname.select(lambda v: getattr(v, classname_var) == var_value)[:]
Above method will work for variable that's isn't relating to other class Entity like:
members = get_instances_from_db(TeamMember, "name", "some_team_member_name")
Finally, my question is: Is it possible to set query to search by integer, and not by Entity object. Or, is there way to use line 'C1'?
Hope I'm clear enough! :)

Updating UDT Set with CQLEngine

I'm new to Cassandra and I'm trying to use CQLEngine ORM to update set column which holds UDT but I can't and documentation doesn't say anything about custom types.
My code is;
class MyType(UserType):
val = columns.Text()
point = columns.Integer()
key = columns.Text()
def __init__(self, val, point, key, **values):
super().__init__(**values)
self.val = val
self.point = point
self.key = key
class MyModel(Model):
myid = columns.UUID(primary_key=True)
set_clm = columns.Set(columns.Integer)
mytype = columns.Set(UserDefinedType(MyType))
def __init__(self, set_clm, mytype, **values):
super().__init__(**values)
self.myid = uuid4()
self.set_clm = set_clm
self.mytype = mytype
s = MyModel.objects(myid="2b3adb7d-9e68-49fc-9aa0-26dbec607f9d").update(
mytype__add=set(MyType(val="1", point=2, key="3"))
)
MyModel initially holds NULL in set but when I try to update it, I get the following error:
cassandra.InvalidRequest: Error from server: code=2200 [Invalid query] message="Invalid set literal for mytype: value 'point' is not of type frozen<mytype>"
'point' is not of type frozen<mytype> -> This part randomly changes whenever I rerun the code (next time I'd run, I'd get the same error for 'val' column etc).
Can anyone help me how I can add a UDT set?
OK. I've solved it. I'm writing it down for people who'd find it on Google.
This is the correct way of adding to a set: mytype__add={MyType(val="1", point=2, key="3")}
and also implement the __hash__ function for MyType such as:
def __hash__():
return hash(self.__repr__())
but with a smarter __hash__ function. It's just an example. Hope it helps to someone else.

Categories