Populating SQLAlchemy datetime column from other table column values?

Viewed 100

What's the best method for populating/creating a datetime column in a Parent table from values in a Child table please? I am parsing reports and wish to automatically populate the Parent.datetime column with integer values from the child.name & child.value columns.

I have the following tables/classes setup (examples for brevity)

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    datetime = Column(DateTime)
    children = relationship("Child", back_populates="parent")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    value = Column(String)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent", back_populates="children")

Parent.children = relationship(
    "Parent", order_by=Child.id, back_populates="parent")

and the following saved in my child table

id name      value parent_id
2  DATEDAY   4     1
3  DATEMON   8     1
4  DATEYEAR  21    1
5  UTCHR     11    1
6  UTCMIN    22    1
7  UTCSEC    33    1

I tried to follow the sqlalchemy 1.4 Documentation specifically relating to column_property() and also this great blog however I went cross eyed when it came to the query.

I figured something like datetime = column_property(some query.where(Child.parent_id == id)) but then couldn't work out how to make it a datetime object.

Then I figured a hybrid expression might work but then was concerned about missing values or just returning None and I went cross-eyed with the query.

Thanks in advance, any help would be much appreciated. First time caller/poster, long time listener.

Update

Adding column_property() look-up for each of the values, the date_exists column and @hybridproperty seems to work. I'm not 100% sure the column_property(exists([DATEDAY, DATEMON, DATEYEAR, UTCHR, UTCMIN, UTCSEC])) is good practice but it seems to work. Also I'm not too happy that date_exists column defaults to None.

I'd appreciate any input on whether there are any issues foreseen with this or if there is a more pythonistic approach.

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    value = Column(String)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent", back_populates="children")

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    datetime = Column(DateTime)
    children = relationship("Child", back_populates="parent")
    DATEDAY = column_property(select([Child.value]).\
        where(and_(Child.name == 'DATEDAY',Child.parent_id == id)))
    DATEMON = column_property(select([Child.value]).\
        where(and_(Child.name == 'DATEMON',Child.parent_id == id)))
    DATEYEAR = column_property(select([Child.value]).\
        where(and_(Child.name == 'DATEYEAR',Child.parent_id == id)))
    UTCHR =  column_property(select([Child.value]).\
        where(and_(Child.name == 'UTCHR',Child.parent_id == id)))
    UTCMIN = column_property(select([Child.value]).\
        where(and_(Child.name == 'UTCMIN',Child.parent_id == id)))
    UTCSEC = column_property(select([Child.value]).\
        where(and_(Child.name == 'UTCSEC',Child.parent_id == id)))
    date_exists = column_property(exists([DATEDAY, DATEMON, DATEYEAR, UTCHR, UTCMIN, UTCSEC]))
    
    @hybridproperty
    def flt_datetime(self):
        if self.date_exists:
            return datetime(
                int(self.DATEYEAR)+2000,
                int(self.DATEMON),
                int(self.DATEDAY),
                int(self.UTCHR),
                int(self.UTCMIN),
                int(self.UTCSEC),
                tzinfo=timezone.utc)
        else: return None
0 Answers
Related