#python #sql
#python #sql
Вопрос:
Приведенный ниже вывод взят из Oracle; где он генерирует инструкции «create table» с использованием прилагаемого пакета. Я загружаю их в инструмент python diff HtmlDiff, который использует difflib под обложками. За каждой таблицей следует ряд команд «alter table add constraint», которые добавляют различные ограничения.
Проблема в том, что нет явного порядка команд «alter table», и я должен изменить их порядок после создания выходного файла, прежде чем запускать сравнение. Мне нужна помощь в этом; в идеале с использованием python, sed или awk.
Правила будут после каждой строки, содержащей «СОЗДАТЬ ТАБЛИЦУ», до следующей строки, содержащей «СОЗДАТЬ ТАБЛИЦУ», сортировать каждую строку, содержащую «ДОБАВИТЬ ОГРАНИЧЕНИЕ»
Это пример моего вывода:
CREATE TABLE T1
( BOOK_ID NUMBER NOT NULL ENABLE,
LOCATION_ID NUMBER NOT NULL ENABLE,
NAME VARCHAR2(255) NOT NULL ENABLE,
LEGAL_ENTITY VARCHAR2(255) NOT NULL ENABLE,
STATUS CHAR(1) NOT NULL ENABLE
) ;
ALTER TABLE T1 ADD CONSTRAINT T1_CHK_1 CHECK ( status IN ( 'A', 'I' , 'T' ) ) ENABLE;
ALTER TABLE T1 ADD CONSTRAINT T1_PK PRIMARY KEY (BOOK_ID) ENABLE;
ALTER TABLE T1 ADD CONSTRAINT T1_AK_1 UNIQUE (NAME) ENABLE;
ALTER TABLE T1 ADD CONSTRAINT T1_FK_1 FOREIGN KEY (LOCATION_ID) REFERENCES T6 (LOCATION_ID) ENABLE;
CREATE TABLE T2
(
BUCKET_ID NUMBER NOT NULL ENABLE,
DATA_LOAD_SESSION_ID NUMBER,
IS_LOCKED CHAR(1) NOT NULL ENABLE,
LOCK_DATE_TIME DATE
) ;
ALTER TABLE T2 ADD CONSTRAINT CKC_IS_LOCKED_BUCKET CHECK (IS_LOCKED in ('T','F')) ENABLE;
ALTER TABLE T2 ADD CONSTRAINT T2_PK PRIMARY KEY (BUCKET_ID) ENABLE;
ALTER TABLE T2 ADD CONSTRAINT T2_FK_2 FOREIGN KEY (RRDB_STAGING_TABLE_ID) REFERENCES T4 (RRDB_STAGING_TABLE_ID) ENABLE;
CREATE TABLE T3
( VALUE_DATE DATE,
NODE_ID NUMBER,
RESULT_UID VARCHAR2(255),
LATEST_EOD_SING_VAL_RESULT_ID NUMBER NOT NULL ENABLE
)
ALTER TABLE T3 ADD CONSTRAINT T3_PK PRIMARY KEY (VALUE_DATE, NODE_ID, RESULT_UID) ENABLE;
Желаемый результат: единственное отличие заключается в порядке строк «ДОБАВИТЬ ОГРАНИЧЕНИЕ»
CREATE TABLE T1
( BOOK_ID NUMBER NOT NULL ENABLE,
LOCATION_ID NUMBER NOT NULL ENABLE,
NAME VARCHAR2(255) NOT NULL ENABLE,
LEGAL_ENTITY VARCHAR2(255) NOT NULL ENABLE,
STATUS CHAR(1) NOT NULL ENABLE
) ;
ALTER TABLE T1 ADD CONSTRAINT T1_AK_1 UNIQUE (NAME) ENABLE;
ALTER TABLE T1 ADD CONSTRAINT T1_CHK_1 CHECK ( status IN ( 'A', 'I' , 'T' ) ) ENABLE;
ALTER TABLE T1 ADD CONSTRAINT T1_FK_1 FOREIGN KEY (LOCATION_ID) REFERENCES T6 (LOCATION_ID) ENABLE;
ALTER TABLE T1 ADD CONSTRAINT T1_PK PRIMARY KEY (BOOK_ID) ENABLE;
CREATE TABLE T2
(
BUCKET_ID NUMBER NOT NULL ENABLE,
DATA_LOAD_SESSION_ID NUMBER,
IS_LOCKED CHAR(1) NOT NULL ENABLE,
LOCK_DATE_TIME DATE
) ;
ALTER TABLE T2 ADD CONSTRAINT CKC_IS_LOCKED_BUCKET CHECK (IS_LOCKED in ('T','F')) ENABLE;
ALTER TABLE T2 ADD CONSTRAINT T2_FK_2 FOREIGN KEY (RRDB_STAGING_TABLE_ID) REFERENCES T4 (RRDB_STAGING_TABLE_ID) ENABLE;
ALTER TABLE T2 ADD CONSTRAINT T2_PK PRIMARY KEY (BUCKET_ID) ENABLE;
CREATE TABLE T3
( VALUE_DATE DATE,
NODE_ID NUMBER,
RESULT_UID VARCHAR2(255),
LATEST_EOD_SING_VAL_RESULT_ID NUMBER NOT NULL ENABLE
)
ALTER TABLE T3 ADD CONSTRAINT T3_PK PRIMARY KEY (VALUE_DATE, NODE_ID, RESULT_UID) ENABLE;
Ответ №1:
Загрузите все это в строку, затем разделите на «;», чтобы создать массив команд SQL. Зациклите массив и создайте новый отсортированный массив. Передайте биты CREATE TABLE и выделите инструкции ALTER TABLE в отдельный список. отсортируйте() список изменений и расширьте его до результирующего массива. Когда вы закончите, ';n'.join(result_array) ';'
.
Ответ №2:
Быстро и грязно, но я думаю, что это подойдет для вашего случая (наверняка сработало в примере):
conList = []
for ln in f:
if ' ADD CONSTRAINT ' in ln:
conList.append(ln)
else:
for it in sorted(conList):
print it
conList = []
print ln
# finish any unfinished business
for it in sorted(conList):
print it