My django app has a table with a datetime field date_created, which is set default to CURRENT_TIMESTAMP. The database is MySQL.
My model
class HybImages(models.Model):
HIGH = 6
INFORMATIVE = 5
AVERAGE = 4
LOW = 3
QUALITY = (
('HI', 'High'),
('LO', 'Low'),
('AV', 'Average'),
('CH', 'Challenged'),
('TP', 'Top'),
)
pid = models.ForeignKey(Hybrid, db_column='pid', verbose_name='grex', null=True, blank=True,on_delete=models.DO_NOTHING)
form = models.CharField(max_length=50, null=True, blank=True)
name = models.CharField(max_length=100, null=True, blank=True)
rank = models.IntegerField(choices=RANK_CHOICES,default=5)
zoom = models.IntegerField(default=0)
certainty = models.CharField(max_length=20, null=True, blank=True)
source_file_name = models.CharField(max_length=100, null=True, blank=True)
...
...
date_created = models.DateTimeField(auto_now_add=True, null=True)
date_modified = models.DateTimeField(auto_now=True, null=True)
When I update a record to change a certain field (say, rank). I did the following:
>>> from orchiddb.models import HybImages
>>>
>>> id = 39387
>>> image = HybImages.objects.get(pk=id)
>>> image.date_created
datetime.datetime(2019, 5, 24, 15, 28, 29, tzinfo=<UTC>)
>>> image.rank = 1
>>> image.save()
>>> image.date_created
datetime.datetime(2019, 10, 31, 14, 14, 51, 852406, tzinfo=<UTC>)
Why did the date_created value changed (and what 852406 stand for)?
What do I have to do to keep date_created unchanged?
Related
Using FastAPI I can't fetch all the data. For example I have this output :
Response body Download (but the items list is always empty):
[
{
"email": "mmm#gmail.com",
"id": 1,
"is_active": true,
"items": []
},
{
"email": "ee#gmail.com",
"id": 2,
"is_active": true,
"items": []
},
]
Endpoint are for example:
#app.get("/users/", response_model=list[schemas.User])
async def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
#app.get("/users/{user_id}", response_model=schemas.User)
async def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
I have the following schemas (database is PostgreSQL):
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str | None = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
Database is postgresql
Models are (table users and table items):
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
__table_args__ = {'schema': 'socialcampaigns'}
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items_rel = relationship("Item", back_populates="owner_id_rel")
class Item(Base):
__tablename__ = "items"
__table_args__ = {'schema': 'socialcampaigns'}
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
owner = Column(Integer, ForeignKey("socialcampaigns.users.id"))
owner_id_rel = relationship("User", back_populates="items_rel")
Crud code is:
from sqlalchemy.orm import Session
from . import models, schemas
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_users (db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
How to solve it? How do I view the list of Items when viewing users?
I have the following code in my app:
models.py
class MainTable(Base):
__tablename__ = "main_table"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, index=True, nullable=False)
owner = Column(String, index=True)
metas = relationship("ChildTable", back_populates="item")
class ChildTable(Base):
__tablename__ = "child"
id = Column(Integer, primary_key=True, index=True)
segment = Column(Integer)
name = Column(String)
main_name = Column(String, ForeignKey('main_table.name'), nullable=False)
item = relationship("MainTable", back_populates="metas")
__table_args__ = (UniqueConstraint('segment', 'main_name', name='_meta_for_main'),
)
And when I run my app, and create new obj in db:
{
"name": "string",
"owner": "string",
"metas": [
{
"segment": 0,
"name": "string",
"main_name": "string",
}
]
}
I get the following error:
AttributeError: 'MainMetaCreate' object has no attribute '_sa_instance_state'
schemas.py
class EnvironmentMetaBase(BaseModel):
segment: int
name: str
main_name: str
Haw you met the following problem?
Models
class Category(Base):
__tablename__ = 'category'
__table_args__ = ({'schema': 'management'},)
category_id_seq = Sequence('management.category_id_seq')
id = Column(Integer, category_id_seq, server_default=category_id_seq.next_value(),
primary_key=True, unique=True, nullable=False, )
description = Column(String, nullable=False)
class Brand(Base):
__tablename__ = 'brand'
__table_args__ = ({'schema': 'management'},)
brand_id_seq = Sequence('management.brand_id_seq')
id = Column(Integer, brand_id_seq, server_default=brand_id_seq.next_value(),
primary_key=True, unique=True, nullable=False)
description = Column(String, nullable=False)
class Quality(Base):
__tablename__ = 'quality'
__table_args__ = ({'schema': 'management'},)
quality_id_seq = Sequence('management.quality_id_seq')
id = Column(Integer, quality_id_seq, server_default=quality_id_seq.next_value(),
primary_key=True, unique=True, nullable=False)
description = Column(String, nullable=False)
class Product(Base):
# region
__tablename__ = 'product'
__table_args__ = (UniqueConstraint('category_id', 'brand_id', 'description',
name='product_uc'), {'schema': 'operation'})
product_id_seq = Sequence('operation.product_id_seq')
id = Column(Integer, product_id_seq, server_default=product_id_seq.next_value(),
primary_key=True, unique=True, nullable=False)
category_id = Column(Integer, ForeignKey(
'management.category.id'), nullable=False)
brand_id = Column(Integer, ForeignKey(
'management.brand.id'), nullable=False)
description = Column(String, nullable=False)
category = relationship(
'Category', foreign_keys='[Product.category_id]')
brand = relationship(
'Brand', foreign_keys='[Product.brand_id]')
# endregion
#hybrid_property
def full_desc(self):
cte_product = session.query(func.concat(Category.description, ' - ',
Brand.description, ' - ',
self.description).label('desc')) \
.select_from(self) \
.join(Category, Brand) \
.filter(Category.id == self.category_id, Brand.id == self.brand_id) \
.cte('cte_product')
# return session.query(cte_product.c.desc).select_from(self).join(cte_product).filter(self.id == cte_product.c.id).cte('test')
return cte_product.c.desc
#full_desc.expression
def full_desc(cls):
cte_product = session.query(func.concat(Category.description, ' - ',
Brand.description, ' - ',
cls.description).label('desc')) \
.select_from(cls)\
.join(Category, Brand) \
.filter(Category.id == cls.category_id, Brand.id == cls.brand_id) \
.cte('cte_product')
return cte_product.c.desc
Test 1 - Using hybrid_property - Undesired Results
result_1 = session.query(Product.id, Product.full_desc).all()
for i in result_1:
print(i)
Running the code above results in a list of all 'full_desc' repeated for every single 'id', like so:
(1, 'Category6 - Brand1 - Product1')
(2, 'Category6 - Brand1 - Product1')
(3, 'Category6 - Brand1 - Product1')
(4, 'Category6 - Brand1 - Product1')
(5, 'Category6 - Brand1 - Product1')
(6, 'Category6 - Brand1 - Product1')
(7, 'Category6 - Brand1 - Product1')
(8, 'Category6 - Brand1 - Product1')
(9, 'Category6 - Brand1 - Product1')
(1, 'Category5 - Brand2 - Product2')
(2, 'Category5 - Brand2 - Product2')
(3, 'Category5 - Brand2 - Product2')
(4, 'Category5 - Brand2 - Product2')
... 81 rows in total
CTE defined outside models
cte_product = session.query(Product.id.label('id'), func.concat(Category.description, ' - ',
Brand.description, ' - ',
Product.description).label('desc')) \
.select_from(Product) \
.join(Category, Brand) \
.filter(Category.id == Product.category_id, Brand.id == Product.brand_id) \
.cte('cte_product')
Test 2 - Using CTE definition above (outside of Models) - Desired Results - Undesired Method
result_2 = session.query(cte_product.c.id, cte_product.c.desc).all()
for i in result_2:
print(i)
Running the code above results in a list of right desc for each id with no repetition (only 9 rows), like so:
(1, 'Category6 - Brand1 - Product1')
(2, 'Category5 - Brand2 - Product2')
(3, 'Category7 - Brand4 - Product3')
(4, 'Category7 - Brand3 - Product4')
(5, 'Category5 - Brand1 - Product5')
(6, 'Category7 - Brand5 - Product6')
(7, 'Category3 - Brand2 - Product7')
(8, 'Category1 - Brand3 - Product8')
(9, 'Category4 - Brand3 - Product9')
Question
What should I change on the #hybrid_property and/or #hybridproperty.extension to get to the desired result as in Test 2 but using the methods in Test 1? Or is there a better way of doing this altogether?
Environment
SQLAlchemy==1.3.20
SQLAlchemy-Utils==0.36.7
PostgreSQL 13
I am not sure if you should use cte at all. And the non-expression part of the #hybrid_property should not use any queries.
Please see the code below, which should work (using sqlalchemy version 1.4):
#hybrid_property
def full_description(self):
return self.category.description + " - " + self.brand.description + " - " + self.description
#full_description.expression
def full_description(cls):
subq = (
select(
func.concat(
Category.description,
" - ",
Brand.description,
" - ",
cls.description,
)
)
.where(Category.id == cls.category_id).where(Brand.id == cls.brand_id)
.scalar_subquery()
.label("full_desc_subquery")
)
return subq
and respective queries:
# in-memory (not using expressions, but potentially loading categories and brands from the database)
result_1 = session.query(Product).all()
for product in result_1:
print(product.id, product.full_description)
# using .expression - get 'full_description' in one query.
result_2 = session.query(Product.id, Product.full_description).all()
for product_id, fulldesc in result_2:
print(product_id, fulldesc)
, where the latter would produce the following SQL statement:
SELECT product.id,
(SELECT concat(category.description, %(concat_2)s, brand.description, %(concat_3)s, product.description) AS concat_1
FROM category,
brand
WHERE category.id = product.category_id
AND brand.id = product.brand_id) AS full_desc_subquery
FROM product
i am really new to DRM and i have to following problem
I have three related models. Now i want to for each sensor values to the related patient. My models look like:
class Sensor(models.Model):
sensor_name = models.CharField(max_length=200, primary_key=True)
sensor_refreshRate = models.FloatField()
sensor_prio = models.IntegerField(choices=[
(1, 1), (2, 2), (3, 3), (4, 4), ], default='1')
sensor_typ = models.CharField(
max_length=200,
choices=[
('bar', 'bar'), ('pie', 'pie'),
('line', 'line'), ('text', 'text'),
],
default='bar'
)
class Patient(models.Model):
firstName = models.CharField(max_length=200)
lastName = models.CharField(max_length=200)
age = models.IntegerField()
doctor = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
sensor = models.ManyToManyField(Sensor)
class Value(models.Model):
value_date = models.DateTimeField(auto_now_add=True)
value = models.FloatField()
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
Now i would like to send a JSON file which looks like:
[
{
"value": 445.0,
"sensor": "Pressure",
"patient": 3
},
{
"value": 478.0,
"sensor": "Temperature",
"patient": 3
}
]
Now i am not sure how to serialize my JSON.
Thanks in advance
your data models seems incomplete.
There's no link between the Value model and the Patient one.
So first I'd suggest to modify the Value model
class Value(models.Model):
value_date = models.DateTimeField(auto_now_add=True)
value = models.FloatField()
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
then you could create a queryset
qs = Value.objects.filter(.....).values(
'patient_id', 'sensor__sensor_name', 'value'
)
and the write your serializer
class User(Base):
"""
users table
"""
__tablename__ = 'users'
__table_args__ = {
'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'
}
id = Column(INTEGER, primary_key=True)
email = Column(String(64), nullable=False, unique=True)
password = Column(String(64), nullable=False)
name = Column(String(32), nullable=False)
last_login_time = Column(DateTime, default='')
last_login_ip = Column(String(32), default='')
create_time = Column(DateTime, nullable=False)
status = Column(SMALLINT, default=0)
role = relationship("Role",
secondary="role_user",
backref=backref('user'))
def __init__(self, email, password, name, last_login_time=now,
last_login_ip='0', create_time=now, status=0):
self.email = email
self.password = md5(password)
self.name = name
self.last_login_time = last_login_time
self.last_login_ip = last_login_ip
self.create_time = create_time
self.status = status
def __repr__(self):
return "<User('%s', '%s')>" % (self.name, self.email)
class Role(Base):
"""
roles table
"""
__tablename__ = 'roles'
__table_args__ = {
'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'
}
id = Column(SMALLINT(5), primary_key=True)
name = Column(String(32), nullable=False, unique=True)
def __init__(self, name):
self.name = name
def __repr__(self):
return "<Role('%s', '%s')>" % (self.id, self.name)
class role_user(Base):
"""
role_user association table
"""
__tablename__ = 'role_user'
__table_args__ = {
'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'
}
user_id = Column(INTEGER, ForeignKey('users.id'), primary_key=True)
role_id = Column(SMALLINT(5), ForeignKey('roles.id'), primary_key=True)
def __init__(self, user_id, role_id):
self.user_id = user_id
self.role_id = role_id
when I create an user,I meet the error:
u1 = User(email='john#example.com', password='12345', name='john')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "<string>", line 2, in __init__
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/instrumentation.py", line 310, in _new_state_if_none
state = self._state_constructor(instance, self)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/util/langhelpers.py", line 582, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/instrumentation.py", line 145, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/event.py", line 409, in __call__
fn(*args, **kw)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/mapper.py", line 2209, in _event_on_first_init
configure_mappers()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/mapper.py", line 2118, in configure_mappers
mapper._post_configure_properties()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/mapper.py", line 1242, in _post_configure_properties
prop.init()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/interfaces.py", line 231, in init
self.do_init()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/properties.py", line 1028, in do_init
self._setup_join_conditions()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/properties.py", line 1102, in _setup_join_conditions
can_be_synced_fn=self._columns_are_mapped
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/relationships.py", line 114, in __init__
self._determine_joins()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/orm/relationships.py", line 180, in _determine_joins
consider_as_foreign_keys=consider_as_foreign_keys
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.egg/sqlalchemy/sql/util.py", line 345, in join_condition
b.foreign_keys,
AttributeError: type object 'role_user' has no attribute 'foreign_keys'
>>>
jiankong#ubuntu:~/git/admin-server$ python manage.py shell
Python 2.6.5 (r265:79063, Oct 1 2012, 22:07:21)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from apps.auth.models import User
>>> u1 = User(email='john#example.com', password='12345', name='john')
what can i do to solve the question? thank you !!
you've got conflicting names for role_user, in that there's a class called role_user and a table with the same name. So secondary="role_user" picks the class object first. Maybe state it like this:
relationship("Role", secondary="role_user.__table__")
EDIT: ideally you'd define "role_user" as a Table only, and define it before you do "secondary". Follow the example at http://docs.sqlalchemy.org/en/latest/orm/relationships.html#many-to-many.