diff --git a/toardb/timeseries/models.py b/toardb/timeseries/models.py index 6582b036d32051cd2f4d5682b72335b5692dbe00..475ca4805a09c5c01ac96104544e7d06e6a722f4 100644 --- a/toardb/timeseries/models.py +++ b/toardb/timeseries/models.py @@ -7,9 +7,6 @@ from .models_core import ( from .models_annotation import ( TimeseriesAnnotation, Base as TimeseriesAnnotationBase) -from .models_role import ( - TimeseriesRole, - Base as TimeseriesRoleBase) from .models_programme import ( TimeseriesProgramme, Base as TimeseriesProgrammBase) @@ -17,8 +14,81 @@ from .models_programme import ( Base = declarative_base() metadata = MetaData() -for declarative_base in [TimeseriesBase, TimeseriesAnnotationBase, TimeseriesRoleBase, TimeseriesProgrammBase]: +from sqlalchemy import Column, ForeignKey, Integer +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() +metadata = Base.metadata + +for declarative_base in [TimeseriesBase, TimeseriesAnnotationBase, TimeseriesProgrammBase]: for (table_name, table) in declarative_base.metadata.tables.items(): metadata._add_table(table_name, table.schema, table) Base.metadata = metadata + +""" +Table "public.timeseries_timeseries_annotations" ++---------------+---------+-----------+----------+---------+ +| Column | Type | Collation | Nullable | Default | ++===============+=========+===========+==========+=========+ +| timeseries_id | integer | | not null | | ++---------------+---------+-----------+----------+---------+ +| annotation_id | integer | | not null | | ++---------------+---------+-----------+----------+---------+ +Indexes: + "timeseries_timeseries_annotations_pkey" PRIMARY KEY, btree (timeseries_id, annotation_id) +Foreign-key constraints: + "timeseries_timeseries_annotations_annotation_id_fkey" FOREIGN KEY (annotation_id) REFERENCES timeseries_annotations(id) + "timeseries_timeseries_annotations_timeseries_id_fkey" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) +""" +##t_timeseries_timeseries_annotations = Table( +## 'timeseries_timeseries_annotations', metadata, +## Column('timeseries_id', ForeignKey('timeseries.id'), primary_key=True, nullable=False), +## Column('annotation_id', ForeignKey('timeseries_annotations.id'), primary_key=True, nullable=False) +##) + +""" +Table "public.timeseries_timeseries_programmes" ++---------------+---------+-----------+----------+---------+ +| Column | Type | Collation | Nullable | Default | ++===============+=========+===========+==========+=========+ +| timeseries_id | integer | | not null | | ++---------------+---------+-----------+----------+---------+ +| programme_id | integer | | not null | | ++---------------+---------+-----------+----------+---------+ +Indexes: + "timeseries_timeseries_programmes_pkey" PRIMARY KEY, btree (timeseries_id, programme_id) +Foreign-key constraints: + "timeseries_timeseries_programmes_programme_id_fkey" FOREIGN KEY (programme_id) REFERENCES timeseries_programmes(id) + "timeseries_timeseries_programmes_timeseries_id_fkey" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) +""" + +##t_timeseries_timeseries_programmes = Table( +## 'timeseries_timeseries_programmes', metadata, +## Column('timeseries_id', ForeignKey('timeseries.id'), primary_key=True, nullable=False), +## Column('programme_id', ForeignKey('timeseries_programmes.id'), primary_key=True, nullable=False) +##) + +## class TimeseriesTimeseriesRoles(Base): +## """ +## Table "public.timeseries_timeseries_roles" +## +---------------+---------+-----------+----------+---------+ +## | Column | Type | Collation | Nullable | Default | +## +===============+=========+===========+==========+=========+ +## | timeseries_id | integer | | not null | | +## +---------------+---------+-----------+----------+---------+ +## | role_id | integer | | not null | | +## +---------------+---------+-----------+----------+---------+ +## Indexes: +## "timeseries_timeseries_roles_pkey" PRIMARY KEY, btree (timeseries_id, role_id) +## Foreign-key constraints: +## "timeseries_timeseries_roles_role_id_fkey" FOREIGN KEY (role_id) REFERENCES timeseries_roles(id) +## "timeseries_timeseries_roles_timeseries_id_fkey" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) +## """ + +## __tablename__ = 'timeseries_timeseries_roles' + +## timeseries_id = Column(Integer, ForeignKey(Timeseries.id), primary_key=True, nullable=False) +## role_id = Column(Integer, ForeignKey(TimeseriesRole.id), primary_key=True, nullable=False) + + diff --git a/toardb/timeseries/models_core.py b/toardb/timeseries/models_core.py index a0c304acc40045cb955c670ca879fdbce377f25c..f0d9556255e56b4da54f7aae18987f33beda5457 100644 --- a/toardb/timeseries/models_core.py +++ b/toardb/timeseries/models_core.py @@ -4,16 +4,118 @@ class Timeseries (Base) ======================= """ from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, String, \ - Text, CheckConstraint, UniqueConstraint -#from sqlalchemy.orm import relationship + Text, CheckConstraint, UniqueConstraint, PrimaryKeyConstraint, \ + Table +from sqlalchemy.orm import relationship from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.ext.declarative import declarative_base from toardb.stationmeta.models import StationmetaCore from toardb.variables.models import Variable +from toardb.contacts.models import Person Base = declarative_base() metadata = Base.metadata +# the problem is pytest!!! +# pytest does not accept strings within ForeignKey, relationship, ... +# forward declarations +# (because of now commented line with relationship +class TimeseriesRole(Base): + __tablename__ = 'timeseries_roles' + id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_roles_id_seq'::regclass)")) + +class Timeseries(Base): + __tablename__ = 'timeseries' + id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_id_seq'::regclass)")) + +##timeseries_timeseries_roles = Table('timeseries_timeseries_roles', Base.metadata, +## Column('timeseries_id', Integer, ForeignKey('public.timeseries.id')), +## Column('role_id', Integer, ForeignKey('public.timeseries_roles.id')) +##) + +#timeseries_timeseries_roles = Table('timeseries_timeseries_roles', Base.metadata, +# Column('timeseries_id', Integer, ForeignKey(Timeseries.id)), +# Column('role_id', Integer, ForeignKey(TimeseriesRole.id)) +#) + +class TimeseriesTimeseriesRoles(Base): + """ + Table "public.timeseries_timeseries_roles" + +---------------+---------+-----------+----------+---------+ + | Column | Type | Collation | Nullable | Default | + +===============+=========+===========+==========+=========+ + | timeseries_id | integer | | not null | | + +---------------+---------+-----------+----------+---------+ + | role_id | integer | | not null | | + +---------------+---------+-----------+----------+---------+ + Indexes: + "timeseries_timeseries_roles_pkey" PRIMARY KEY, btree (timeseries_id, role_id) + Foreign-key constraints: + "timeseries_timeseries_roles_role_id_fkey" FOREIGN KEY (role_id) REFERENCES timeseries_roles(id) + "timeseries_timeseries_roles_timeseries_id_fkey" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) + """ + + __tablename__ = 'timeseries_timeseries_roles' + __table_args__ = ( + PrimaryKeyConstraint('timeseries_id', 'role_id'), + ) +# timeseries_id = Column(ForeignKey(Timeseries.id, deferrable=True, initially='DEFERRED')) +# role_id = Column(ForeignKey(TimeseriesRole.id, deferrable=True, initially='DEFERRED')) + timeseries_id = Column(ForeignKey('timeseries.id', deferrable=True, initially='DEFERRED')) + role_id = Column(ForeignKey('timeseries_roles.id', deferrable=True, initially='DEFERRED')) +## timeseries = relationship(Timeseries, back_populates = 'role') +## roles = relationship(TimeseriesRole, back_populates = 'timeseries') + + +class TimeseriesRole(Base): + """ Table "public.timeseries_roles" + + +---------------+---------+-----------+----------+----------------------------------------------+ + | Column | Type | Collation | Nullable | Default | + +===============+=========+===========+==========+==============================================+ + | id | integer | | not null | nextval('timeseries_roles_id_seq'::regclass) | + +---------------+---------+-----------+----------+----------------------------------------------+ + | role | integer | | not null | | + +---------------+---------+-----------+----------+----------------------------------------------+ + | status | integer | | not null | | + +---------------+---------+-----------+----------+----------------------------------------------+ + | person_id | integer | | not null | | + +---------------+---------+-----------+----------+----------------------------------------------+ + Indexes: + "timeseries_roles_pkey" PRIMARY KEY, btree (id) + "timeseries_roles_role_person_id_uniq" UNIQUE CONSTRAINT, btree (role, person_id) + "timeseries_roles_person_id" btree (person_id) + Check constraints: + "timeseries_roles_role_check" CHECK (role >= 0) + "timeseries_roles_status_check" CHECK (status >= 0) + Foreign-key constraints: + "timeseries_roles_person_id_3e26200e_fk_persons_id" FOREIGN KEY (person_id) REFERENCES persons(id) DEFERRABLE INITIALLY DEFERRED + """ + + __tablename__ = 'timeseries_roles' + __table_args__ = ( + CheckConstraint('role >= 0'), + CheckConstraint('status >= 0'), + UniqueConstraint('role', 'person_id'), + {'extend_existing': True} + ) + + id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_roles_id_seq'::regclass)")) + role = Column(Integer, nullable=False) + status = Column(Integer, nullable=False) +# do not use string declaration here (not working for pytest) +# use the explicit class name here, +# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U + person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True) +# how to reactivate the following line +# person = relationship('Person') + +# how to reactivate the following line?! + timeseries_id = Column(Integer, ForeignKey(Timeseries.id), nullable=False) +# timeseries = relationship(Timeseries, secondary=timeseries_timeseries_roles, backref="timeseries") + timeseries = relationship(Timeseries, secondary=TimeseriesTimeseriesRoles.__table__, backref="timeseries") + + class Timeseries(Base): """ Table "public.timeseries" @@ -53,22 +155,22 @@ class Timeseries(Base): +---------------------+--------------------------+-----------+----------+----------------------------------------+ Indexes: "timeseries_pkey" PRIMARY KEY, btree (id) - "timeseries_station_id_variable_id_label_055cfe3a_uniq" UNIQUE CONSTRAINT, btree (station_id, variable_id, label) - "timeseries_station_id_0f4fed9c" btree (station_id) - "timeseries_variable_id_dd9603f5" btree (variable_id) + "timeseries_station_id_variable_id_label_uniq" UNIQUE CONSTRAINT, btree (station_id, variable_id, label) + "timeseries_station_id" btree (station_id) + "timeseries_variable_id" btree (variable_id) Check constraints: "timeseries_access_rights_check" CHECK (access_rights >= 0) "timeseries_aggregation_check" CHECK (aggregation >= 0) "timeseries_order_check" CHECK ("order" >= 0) "timeseries_sampling_frequency_check" CHECK (sampling_frequency >= 0) Foreign-key constraints: - "timeseries_station_id_0f4fed9c_fk_stationmeta_core_id" FOREIGN KEY (station_id) REFERENCES stationmeta_core(id) DEFERRABLE INITIALLY DEFERRED - "timeseries_variable_id_dd9603f5_fk_variables_id" FOREIGN KEY (variable_id) REFERENCES variables(id) DEFERRABLE INITIALLY DEFERRED + "timeseries_station_id_fk_stationmeta_core_id" FOREIGN KEY (station_id) REFERENCES stationmeta_core(id) DEFERRABLE INITIALLY DEFERRED + "timeseries_variable_id_fk_variables_id" FOREIGN KEY (variable_id) REFERENCES variables(id) DEFERRABLE INITIALLY DEFERRED Referenced by: - TABLE "data2" CONSTRAINT "data2_timeseries_id_a38c5a1a_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED - TABLE "data" CONSTRAINT "data_timeseries_id_a38c5a1a_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED - TABLE "timeseries_annotations" CONSTRAINT "timeseries_annotations_timeseries_id_02014000_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED - TABLE "timeseries_roles" CONSTRAINT "timeseries_roles_timeseries_id_13b7edfd_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED + TABLE "data" CONSTRAINT "data_timeseries_id_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED + TABLE "timeseries_timeseries_annotations" CONSTRAINT "timeseries_timeseries_annotations_timeseries_id_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED + TABLE "timeseries_timeseries_roles" CONSTRAINT "timeseries_timeseries_roles_timeseries_id_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED + TABLE "timeseries_timeseries_programmes" CONSTRAINT "timeseries_timeseries_programmes_timeseries_id_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED """ __tablename__ = 'timeseries' @@ -77,7 +179,9 @@ class Timeseries(Base): CheckConstraint('access_rights >= 0'), CheckConstraint('aggregation >= 0'), CheckConstraint('sampling_frequency >= 0'), - UniqueConstraint('station_id', 'variable_id', 'label') + UniqueConstraint('station_id', 'variable_id', 'label'), + {'schema': 'public', + 'extend_existing': True} ) id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_id_seq'::regclass)")) @@ -105,3 +209,4 @@ class Timeseries(Base): # how to reactivate the following two lines?! # station = relationship('StationmetaCore') # variable = relationship('Variable') + diff --git a/toardb/timeseries/models_role.py b/toardb/timeseries/models_role.py deleted file mode 100644 index eff9e460da536fee9daecab808048e81389c5266..0000000000000000000000000000000000000000 --- a/toardb/timeseries/models_role.py +++ /dev/null @@ -1,63 +0,0 @@ -# coding: utf-8 -""" -class TimeseriesRole (Base) -=========================== -""" -from sqlalchemy import Column, ForeignKey, Integer, text, \ - CheckConstraint, UniqueConstraint -#from sqlalchemy.orm import relationship -from sqlalchemy.ext.declarative import declarative_base -from toardb.contacts.models import Person -from .models_core import Timeseries - -Base = declarative_base() -metadata = Base.metadata - -class TimeseriesRole(Base): - """ Table "public.timeseries_roles" - - +---------------+---------+-----------+----------+----------------------------------------------+ - | Column | Type | Collation | Nullable | Default | - +===============+=========+===========+==========+==============================================+ - | id | integer | | not null | nextval('timeseries_roles_id_seq'::regclass) | - +---------------+---------+-----------+----------+----------------------------------------------+ - | role | integer | | not null | | - +---------------+---------+-----------+----------+----------------------------------------------+ - | status | integer | | not null | | - +---------------+---------+-----------+----------+----------------------------------------------+ - | person_id | integer | | not null | | - +---------------+---------+-----------+----------+----------------------------------------------+ - | timeseries_id | integer | | not null | | - +---------------+---------+-----------+----------+----------------------------------------------+ - Indexes: - "timeseries_roles_pkey" PRIMARY KEY, btree (id) - "timeseries_roles_timeseries_id_role_person_id_d888d4bf_uniq" UNIQUE CONSTRAINT, btree (timeseries_id, role, person_id) - "timeseries_roles_person_id_3e26200e" btree (person_id) - "timeseries_roles_timeseries_id_13b7edfd" btree (timeseries_id) - Check constraints: - "timeseries_roles_role_check" CHECK (role >= 0) - "timeseries_roles_status_check" CHECK (status >= 0) - Foreign-key constraints: - "timeseries_roles_person_id_3e26200e_fk_persons_id" FOREIGN KEY (person_id) REFERENCES persons(id) DEFERRABLE INITIALLY DEFERRED - "timeseries_roles_timeseries_id_13b7edfd_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED - """ - - __tablename__ = 'timeseries_roles' - __table_args__ = ( - CheckConstraint('role >= 0'), - CheckConstraint('status >= 0'), - UniqueConstraint('timeseries_id', 'role', 'person_id') - ) - - id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_roles_id_seq'::regclass)")) - role = Column(Integer, nullable=False) - status = Column(Integer, nullable=False) -# do not use string declaration here (not working for pytest) -# use the explicit class name here, -# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U - person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True) - timeseries_id = Column(ForeignKey(Timeseries.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True) -# how to reactivate the following two lines?! -# person = relationship('Person') -# timeseries = relationship('Timeseries') -