Commit 018f2c63 authored by mlocatelli's avatar mlocatelli

create_database script and files

parent 9e6fff3b
Pipeline #2502 passed with stages
in 11 minutes and 7 seconds
......@@ -161,7 +161,7 @@ additional and different datasources.
"""
from sqlalchemy import Column, Text, Boolean, ForeignKey, VARCHAR
from sqlalchemy.orm import class_mapper, ColumnProperty, relationship
import sqlalchemy
from .database import Base, get_session, get_engine
from chemicalchecker.util import logged
......@@ -240,7 +240,7 @@ class Dataset(Base): # NS Base is a base class from SQLAlchemy, no __init__??
@staticmethod
def _table_exists():
engine = get_engine()
return engine.dialect.has_table(engine, Dataset.__tablename__)
return sqlalchemy.inspect(engine).has_table(Dataset.__tablename__)
@staticmethod
def _table_attributes():
......@@ -272,7 +272,16 @@ class Dataset(Base): # NS Base is a base class from SQLAlchemy, no __init__??
filename(str): Path to a CSV file.
"""
import pandas as pd
df = pd.read_csv(filename, delimiter=";")
df = pd.read_csv(filename)
# The boolean columns must be changed to boolean values otherwise
# SQLalchmy passes strings
df.unknowns = df.unknowns.apply(lambda x: False if x == 'f' else True)
df.discrete = df.discrete.apply(lambda x: False if x == 'f' else True)
df.exemplary = df.exemplary.apply(lambda x: False if x == 'f' else True)
df.public = df.public.apply(lambda x: False if x == 'f' else True)
df.essential = df.essential.apply(lambda x: False if x == 'f' else True)
# check columns
needed_cols = Dataset._table_attributes()
if needed_cols != list(df.columns):
......@@ -347,8 +356,7 @@ class DatasetHasDatasource(Base):
@staticmethod
def _table_exists():
engine = get_engine()
return engine.dialect.has_table(engine,
DatasetHasDatasource.__tablename__)
return sqlalchemy.inspect(engine).has_table(DatasetHasDatasource.__tablename__)
@staticmethod
def _table_attributes():
......
......@@ -6,6 +6,7 @@ using the :mod:`~chemicalchecker.util.download` class and interfacing them
with the Dataset table.
"""
import os
import sqlalchemy
from sqlalchemy import Column, Text, Boolean
from sqlalchemy.orm import class_mapper, ColumnProperty, relationship
......@@ -70,7 +71,7 @@ class Datasource(Base):
@staticmethod
def _table_exists():
engine = get_engine()
return engine.dialect.has_table(engine, Datasource.__tablename__)
return sqlalchemy.inspect(engine).has_table(Datasource.__tablename__)
@staticmethod
def _table_attributes():
......
......@@ -15,6 +15,7 @@ Example::
import os
import datetime
from time import time
import sqlalchemy
from sqlalchemy.dialects import postgresql
from sqlalchemy import Column, Text, Boolean, ForeignKey, VARCHAR
from sqlalchemy.orm import class_mapper, ColumnProperty, relationship
......@@ -72,7 +73,7 @@ class Molrepo(Base):
@staticmethod
def _table_exists():
engine = get_engine()
return engine.dialect.has_table(engine, Molrepo.__tablename__)
return sqlalchemy.inspect(engine).has_table(Molrepo.__tablename__)
@staticmethod
def _table_attributes():
......@@ -140,6 +141,11 @@ class Molrepo(Base):
"""
import pandas as pd
df = pd.read_csv(filename)
# The boolean columns must be changed to boolean values otherwise
# SQLalchmy passes strings
df.universe = df.universe.apply(lambda x: False if x == 'f' else True)
df.essential = df.essential.apply(lambda x: False if x == 'f' else True)
# check columns
needed_cols = Molrepo._table_attributes()
if needed_cols != list(df.columns):
......@@ -398,7 +404,7 @@ class MolrepoHasMolecule(Base):
@staticmethod
def _table_exists():
engine = get_engine()
return engine.dialect.has_table(engine, MolrepoHasMolecule.__tablename__)
return sqlalchemy.inspect(engine).has_table(MolrepoHasMolecule.__tablename__)
@staticmethod
def _table_attributes():
......@@ -453,8 +459,7 @@ class MolrepoHasDatasource(Base):
@staticmethod
def _table_exists():
engine = get_engine()
return engine.dialect.has_table(engine,
MolrepoHasDatasource.__tablename__)
return sqlalchemy.inspect(engine).has_table(MolrepoHasDatasource.__tablename__)
@staticmethod
def _table_attributes():
......
/* When the table datasource is updated, make sure the foregin key constraints remain*/
ALTER TABLE dataset_has_datasource
ADD CONSTRAINT "dataset_has_datasource_datasource_name_fkey"
FOREIGN KEY (datasource_name)
REFERENCES datasource(datasource_name);
ALTER TABLE molrepo_has_datasource
ADD CONSTRAINT "molrepo_has_datasource_datasource_name_fkey"
FOREIGN KEY (datasource_name)
REFERENCES datasource(datasource_name);
# Nico, 19/06/2020
# Update the datasource table from cc_package database on aloy-dbsrv
# Don't forget to remove the previous datasource table first
from chemicalchecker.database import Datasource, Dataset, DatasetHasDatasource, Molrepo, MolrepoHasDatasource
from chemicalchecker.util import Config
import os
DatasourceFile="datasource.csv"
DatasetFile="dataset.csv"
DatasetDatasourceFile="dataset_has_datasource.csv"
MolrepoFile="molrepo.csv"
MolrepoDatasourceFile="molrepo_has_datasource.csv"
current_dir = os.path.dirname(os.path.abspath(__file__))
# Create DB
command1 ="PGPASSWORD={} psql -h {} -U {} -tc \"SELECT 1 FROM pg_database WHERE datname = \'{}\';\" | grep -q 1" \
.format(Config().DB.password, Config().DB.host, Config().DB.user, Config().DB.database)
res = os.system(command1)
if res == 0:
raise Exception("Database '{}' already exist".format(Config().DB.database))
else:
command1 = "PGPASSWORD={} psql -h {} -U {} -c \"CREATE DATABASE {}\"".format(Config().DB.password, Config().DB.host, Config().DB.user, Config().DB.database)
os.system(command1)
print("DB CREATED---->{}".format(Config().DB.database))
# check if Datasource table is already present
if Datasource._table_exists():
Datasource._drop_table()
print("'datasource' table already exists in database '{}' \n Dropped it".format(Config().DB.database))
print("Creating the table 'datasource' in database '{}'".format(Config().DB.database))
Datasource._create_table()
print("Populating 'datasource' table with data")
Datasource.from_csv(os.path.join(current_dir, DatasourceFile))
print("TABLE CREATED---->datasource")
# check if Dataset table is already present
if Dataset._table_exists():
print("'dataset' table already exists in database '{}' \n Dropped it ".format(Config().DB.database))
print("Creating the table 'dataset' in database '{}'".format(Config().DB.database))
Dataset._create_table()
print("Populating 'dataset' table with data")
Dataset.from_csv(os.path.join(current_dir,DatasetFile))
print("TABLE CREATED---->dataset")
# check if dataset_has_datasource table is already present
if DatasetHasDatasource._table_exists():
DatasetHasDatasource._drop_table()
print("'dataset_has_datasource' table already exists in database '{}' \n Dropped it".format(Config().DB.database))
else:
dataset_exists = Dataset._table_exists()
datasource_exists = Datasource._table_exists()
if dataset_exists and datasource_exists:
print("Creating the table 'dataset_has_datasource' in database '{}'".format(Config().DB.database))
DatasetHasDatasource._create_table()
print("Populating 'dataset_has_datasource' table with data")
DatasetHasDatasource.from_csv(os.path.join(current_dir,DatasetDatasourceFile))
print("TABLE CREATED---->dataset_has_datasource")
else:
raise Exception("It is not possble to create 'dataset_has_datasource' because either 'dataset' or 'datasource' table doesn't exist: \
dataset {} - datasource {}".format(dataset_exists, datasource_exists))
# check if Molrepo table is already present
if Molrepo._table_exists():
Molrepo._drop_table()
print("'molrepo' table already exists in database '{}' \n Dropped it".format(Config().DB.database))
print("Creating the table 'molrepo' in database '{}'".format(Config().DB.database))
Molrepo._create_table()
print("Populating 'molrepo' table with data")
Molrepo.from_csv(os.path.join(current_dir,MolrepoFile))
print("TABLE CREATED---->molrepo")
# check if molrepo_has_datasource table is already present
if MolrepoHasDatasource._table_exists():
MolrepoHasDatasource._drop_table()
print("'molrepo_has_datasource' table already exists in database '{}' \n Dropped it".format(Config().DB.database))
else:
molrepo_exists = Molrepo._table_exists()
datasource_exists = Datasource._table_exists()
if molrepo_exists and datasource_exists:
print("Creating the table 'molrepo_has_datasource' in database '{}'".format(Config().DB.database))
MolrepoHasDatasource._create_table()
print("Populating 'molrepo_has_datasource' table with data")
MolrepoHasDatasource.from_csv(os.path.join(current_dir,MolrepoDatasourceFile))
print("TABLE CREATED---->molrepo_has_datasource")
else:
raise Exception("Itis not possble to create 'molrepo_has_datasource' because either 'molrepo' or 'datasource' table doesn't exist: \
dataset {} - datasource {}".format(molrepo_exists, datasource_exists))
# Nico, 19/06/2020
# Update the datasource table from cc_package database on aloy-dbsrv
# Don't forget to remove the previous datasource table first
from chemicalchecker.database import Datasource
import os
CSVfileIn="current_resource_CSV"
sql_file1="remove_foreign_constraints.sql"
sql_file2="add_foreign_constraints.sql"
current_dir = os.path.dirname(os.path.abspath(__file__))
os.environ['CC_CONFIG'] = os.path.join(current_dir,'../configs/cc_package.json')
# check if Datasource table is there
if Datasource._table_exists():
print("Removing previous table 'datasource' in database 'cc_package'")
command1="psql -h aloy-dbsrv -d cc_package <"+sql_file1 #remove fconstraints and make a backup table
os.system(command1)
Datasource._drop_table()
# create the Datasource table
print("Creating the table 'datasource' in database 'cc_package'")
Datasource._create_table()
# populate it with Datasources needed for exemplary Datasets
Datasource.from_csv(CSVfileIn)
print("TABLE CREATED---->datasource")
# Ensure the foreign key constraints remain as such (no password needed for sbnb-adm)
command2="psql -h aloy-dbsrv -d cc_package <"+sql_file2
os.system(command2) # Add foreign constraints
backup/datasource_19Jun2020.csv
\ No newline at end of file
dataset_code,datasource_name
B1.001,chembl
B1.001,drugbank
B1.001,chembl_target_predictions
......@@ -26,19 +27,16 @@ C5.001,inBio_Map_core
C5.001,metaphors_9606
C5.001,metaphors_id_conversion
C5.001,uniprot_HUMAN_9606
D1.001,GSE70138_Broad_LINCS_gene_info
D1.001,GSE70138_Broad_LINCS_inst_info
D1.001,GSE70138_Broad_LINCS_Level5_COMPZ
D1.001,GSE70138_Broad_LINCS_pert_info_date
D1.001,GSE70138_Broad_LINCS_pert_info
D1.001,GSE70138_Broad_LINCS_sig_info
D1.001,GSE70138_Broad_LINCS_sig_metrics
D1.001,GSE92742_Broad_LINCS_gene_info
D1.001,GSE92742_Broad_LINCS_Level5_COMPZ
D1.001,GSE92742_Broad_LINCS_pert_info
D1.001,GSE92742_Broad_LINCS_pert_metrics
D1.001,GSE92742_Broad_LINCS_sig_info
D1.001,GSE92742_Broad_LINCS_sig_metrics
D1.001,cellinfo_beta
D1.001,geneinfo_beta
D1.001,compoundinfo_beta
D1.001,instinfo_beta
D1.001,siginfo_beta
D1.001,level5_beta_trt_cp_n720216x12328
D1.001,level5_beta_trt_oe_n34171x12328
D1.001,level5_beta_trt_sh_n238351x12328
D2.001,DTP_NCI60_ZSCORE
D3.001,mosaic
D3.001,mosaic_all_collections
......
datasource_name,description,is_db,url,username,password,filename,calcdata
cmaup,CMAUP Natural Products Database. This database is a meta-resource.,f,http://bidd2.nus.edu.sg/CMAUP/downloadFiles/CMAUPv1.0_download_Ingredients_All.txt,,,CMAUPv1.0_download_Ingredients_All.txt,f
cmaup,CMAUP Natural Products Database. This database is a meta-resource.,f,http://bidd.group/CMAUP/downloadFiles/CMAUPv1.0_download_Ingredients_All.txt,,,CMAUPv1.0_download_Ingredients_All.txt,f
repohub,"Drug Repurposing Hub database, accessible from https://clue.io/repurposing-app, is a curated resource of approved and experimental drugs. It has the advantage of being tighthly integrated within the Broad LINCS environment.",f,file:///aloy/web_checker/repo_data/Repurposing_Hub_export_201904.txt,,,Repurposing_Hub_export_201904.txt,f
chembl_uniprot_mapping,Mapping between ChEMBL target IDs and Uniprot ACs.,f,ftp://ftp.ebi.ac.uk/pub/databases/chembl/ChEMBLdb/latest/chembl_uniprot_mapping.txt,,,chembl_uniprot_mapping.txt,f
kegg_br,,f,http://www.genome.jp/kegg-bin/download_htext?htext=br08303.keg&format=htext&filedir=,,,br08303.keg,f
deepcodex_map,DeepCodex uses a deep-learned embedding of gene expression profiles to find chemical and genetic perturbations with similar biological effects.,f,file:///aloy/web_checker/repo_data/deepcodex/dcx_map.csv,,,dcx_map.csv,f
bindingdb,,f,file:///aloy/scratch/sbnb-adm/checker/local_downloads/BindingDB_All.tsv.zip,,,BindingDB_All.tsv,f
chebi_lite,,f,ftp://ftp.ebi.ac.uk/pub/databases/chebi/SDF/ChEBI_lite_3star.sdf.gz,,,ChEBI_lite_3star.sdf,f
chembl,,t,ftp://ftp.ebi.ac.uk/pub/databases/chembl/ChEMBLdb/latest/chembl_*_postgresql.tar.gz,,,chembl_*/chembl_*_postgresql/chembl_*_postgresql.dmp,f
chembl,,t,ftp://ftp.ebi.ac.uk/pub/databases/chembl/ChEMBLdb/latest/chembl_*_postgresql.tar.gz,,,chembl_*_postgresql/chembl_*_postgresql.dmp,f
CTD_chemicals_diseases,,f,http://ctdbase.org/reports/CTD_chemicals_diseases.tsv.gz,,,CTD_chemicals_diseases.tsv,f
drugbank,,f,https://www.drugbank.ca/releases/5-1-0/downloads/all-full-database,oriol.guitart@irbbarcelona.org,sbnbAloy,full database.xml,f
GSE70138_Broad_LINCS_pert_info_date,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_pert_info_*.txt.gz,,,GSE70138_Broad_LINCS_pert_info_*.txt,f
GSE92742_Broad_LINCS_pert_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE92nnn/GSE92742/suppl/GSE92742_Broad_LINCS_pert_info.txt.gz,,,GSE92742_Broad_LINCS_pert_info.txt,f
GSE92742_Broad_LINCS_pert_info,,f,https://www.ncbi.nlm.nih.gov/geo/download/?acc=GSE92742&format=file&file=GSE92742%5FBroad%5FLINCS%5Fpert%5Finfo%2Etxt%2Egz,,,GSE92742_Broad_LINCS_pert_info.txt,f
GSE70138_Broad_LINCS_pert_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_pert_info.txt.gz,,,,f
mosaic_all_collections,,f,http://mosaic.cs.umn.edu/downloads/RIKEN-Clinical_FINAL/compound_information/sdf/Structural_Data_Files_combined.zip,,,All_Collections.sdf,f
pdb_components,,f,http://ligand-expo.rcsb.org/dictionaries/Components-smiles-stereo-oe.smi,,,Components-smiles-stereo-oe.smi,f
chemicals,,f,http://stitch4.embl.de/download/chemicals.v4.0.tsv.gz,,,chemicals.v4.0.tsv,f
......@@ -19,17 +19,15 @@ smpdb_structures,,f,http://smpdb.ca/downloads/smpdb_structures.zip,,,,f
cellosaurus,,f,ftp://ftp.expasy.org/databases/cellosaurus/cellosaurus.obo,,,,f
chebi,,f,ftp://ftp.ebi.ac.uk/pub/databases/chebi/ontology/chebi.obo,,,,f
gobasic,,f,http://snapshot.geneontology.org/ontology/go-basic.obo,,,,f
GSE70138_Broad_LINCS_gene_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_gene_info*.txt.gz,,,,f
GSE70138_Broad_LINCS_inst_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_inst_info*.txt.gz,,,,f
GSE70138_Broad_LINCS_Level5_COMPZ,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_Level5_COMPZ_n118050x12328*.gctx.gz,,,,f
GSE70138_Broad_LINCS_pert_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_pert_info.txt.gz,,,,f
GSE70138_Broad_LINCS_sig_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_sig_info*.txt.gz,,,,f
GSE70138_Broad_LINCS_sig_metrics,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE70nnn/GSE70138/suppl/GSE70138_Broad_LINCS_sig_metrics*.txt.gz,,,,f
GSE92742_Broad_LINCS_gene_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE92nnn/GSE92742/suppl/GSE92742_Broad_LINCS_gene_info.txt.gz,,,,f
GSE92742_Broad_LINCS_Level5_COMPZ,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE92nnn/GSE92742/suppl/GSE92742_Broad_LINCS_Level5_COMPZ.MODZ_n473647x12328.gctx.gz,,,,f
GSE92742_Broad_LINCS_pert_metrics,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE92nnn/GSE92742/suppl/GSE92742_Broad_LINCS_pert_metrics.txt.gz,,,,f
GSE92742_Broad_LINCS_sig_info,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE92nnn/GSE92742/suppl/GSE92742_Broad_LINCS_sig_info.txt.gz,,,,f
GSE92742_Broad_LINCS_sig_metrics,,f,ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE92nnn/GSE92742/suppl/GSE92742_Broad_LINCS_sig_metrics.txt.gz,,,,f
GSE92742_Broad_LINCS_sig_info,,f, https://www.ncbi.nlm.nih.gov/geo/download/?acc=GSE92742&format=file&file=GSE92742%5FBroad%5FLINCS%5Fsig%5Finfo%2Etxt%2Egz,,,GSE92742_Broad_LINCS_sig_info.txt,f
cellinfo_beta,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/cellinfo_beta.txt,,,cellinfo_beta.txt,f
geneinfo_beta,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/geneinfo_beta.txt,,,geneinfo_beta.txt,f
compoundinfo_beta,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/compoundinfo_beta.txt,,,compoundinfo_beta.txt,f
instinfo_beta,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/instinfo_beta.txt,,,instinfo_beta.txt,f
siginfo_beta,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/siginfo_beta.txt,,,siginfo_beta.txt,f
level5_beta_trt_cp_n720216x12328,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/level5/level5_beta_trt_cp_n720216x12328.gctx,,,level5_beta_trt_cp_n720216x12328.gctx,f
level5_beta_trt_oe_n34171x12328,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/level5/level5_beta_trt_oe_n34171x12328.gctx,,,level5_beta_trt_oe_n34171x12328.gctx,f
level5_beta_trt_sh_n238351x12328,,f,https://s3.amazonaws.com/macchiato.clue.io/builds/LINCS2020/level5/level5_beta_trt_sh_n238351x12328.gctx,,,level5_beta_trt_sh_n238351x12328.gctx,f
hgnc_complete,,f,ftp://ftp.ebi.ac.uk/pub/databases/genenames/new/tsv/hgnc_complete_set.txt,,,,f
disease_mappings,,f,http://www.disgenet.org/static/disgenet_ap1/files/downloads/disease_mappings.tsv.gz,,,,f
deepcodex_download,DeepCodex uses a deep-learned embedding of gene expression profiles to find chemical and genetic perturbations with similar biological effects.,f,file:///aloy/web_checker/repo_data/deepcodex/download.zip,,,,f
......
molrepo_name,description,universe,essential
bindingdb,Binding molecular repository,t,t
chebi,,t,t
chembl,Chembl molecular repository,t,t
ctd,,t,t
drugbank,Drugbank molecular repository,t,t
kegg,KEGG molecular repository,t,t
lincs,,t,t
morphlincs,,t,t
mosaic,,t,t
nci60,,t,t
pdb,,t,t
sider,,t,t
smpdb,,t,t
biur_real,ChemistryX Biur real library,f,t
biur_virtual,ChemistryX Biur virtual library,f,t
hmdb,"The Human Metabolome Database (HMDB) is a database containing detailed information about small molecule metabolites found in the human body. It is intended to be used for applications in metabolomics, clinical chemistry, biomarker discovery and general education. The database is designed to contain or link three kinds of data: 1) chemical data, 2) clinical data, and 3) molecular biology/biochemistry data.",f,t
cmaup,CMAUP Natural Products Database. This database is a meta-resource.,f,t
repohub,"Drug Repurposing Hub database, accessible from https://clue.io/repurposing-app, is a curated resource of approved and experimental drugs. It has the advantage of being tighthly integrated within the Broad LINCS environment.",f,t
deepcodex,DeepCodex uses a deep-learned embedding of gene expression profiles to find chemical and genetic perturbations with similar biological effects.,f,t
pharmacodb,PharmacoDB assembles the largest in vitro drug sensitivity screens in a single database.,f,t
touchstone,Reference Clue.io collection,f,
molrepo_name,datasource_name
cmaup,cmaup
repohub,repohub
kegg,kegg_br
deepcodex,deepcodex_map
bindingdb,bindingdb
chebi,chebi_lite
chembl,chembl
ctd,CTD_chemicals_diseases
drugbank,drugbank
lincs,GSE92742_Broad_LINCS_pert_info
morphlincs,morphlincs_LDS-1195
mosaic,mosaic_all_collections
nci60,DTP_NCI60_ZSCORE
pdb,pdb_components
sider,chemicals
sider,meddra_all_se
smpdb,smpdb_structures
biur_real,biur_real
biur_virtual,biur_virtual
hmdb,hmdb_metabolites
pharmacodb,pharmacodb
touchstone,GSE92742_Broad_LINCS_pert_info
DROP TABLE IF EXISTS datasourcebckp;
CREATE TABLE datasourcebckp AS TABLE datasource;
ALTER TABLE dataset_has_datasource
DROP CONSTRAINT IF EXISTS "dataset_has_datasource_datasource_name_fkey";
ALTER TABLE molrepo_has_datasource
DROP CONSTRAINT IF EXISTS "molrepo_has_datasource_datasource_name_fkey";
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment