Я использую SQLAlchemy для выполнения операторов SQL в различных базах данных и пытаюсь найти способ определить, является ли оператор SQL (переданным в коннектор в виде строки python). Каков наилучший способ сделать это надежно для нескольких разновидностей SQL?

raw_query = "SELECT * FROM table"
engine = get_engine(username=db_dict['username'],
                              password=db_dict['password'],
                              db=database,
                              hostname=db_dict['hostname'],
                              port=port,
                              db_type=db_dict['type'])
with engine.connect() as db_conn:
    # query database
    result = db_conn.execute(sqlalchemy.text(raw_query))

В приведенном выше, как лучше всего проверить, потребует ли SQL в raw_query больше разрешений, чем только чтение? Или, другими словами, будет ли он вносить изменения в базу данных.

0
pwwolff 30 Май 2023 в 21:00
1
Я не думаю, что есть какой-либо проверенный способ сделать это, кроме гарантии того, что имя пользователя, которое вы используете для выполнения этих операторов, не имеет доступа, который вы не хотите иметь. Наивно, вы можете проверить, что оператор начинается с SELECT. Некоторые регулярные выражения, такие как (^SEL|^SELECT)\s, могут помочь, но, очевидно, не поймают что-то вроде SELECT * FROM sometable; UPDATE sometable SET somecolumn=NULL;.
 – 
JNevill
30 Май 2023 в 21:06
Возможно, это будет полезно: github.com/andialbrecht/sqlparse
 – 
kosciej16
30 Май 2023 в 21:10
Для начала вы можете поискать вхождения UPDATE, INSERT, TRUNCATE, DELETE, DROP и т. д.
 – 
John Gordon
30 Май 2023 в 21:11
Не забудьте WITH, VALUES и TABLE в качестве первого слова, доступного только для чтения.
 – 
jarlh
30 Май 2023 в 21:11
1
SQL Server и Oracle (возможно, среди некоторых других) также поддерживают SELECT INTO, что может быть мутативным, несмотря на использование SELECT. Однако - это очень похоже на проблему XY - если вы в каком-то отношении обеспокоены мутациями базы данных из-за ненадежного пользовательского ввода, вам, вероятно, следует немного больше подумать о своей архитектуре безопасности.
 – 
esqew
30 Май 2023 в 21:21

1 ответ

В большинстве случаев, когда вы запускаете операторы sql через некоторые библиотеки, вы должны получить количество измененных полей, созданных полей или что-то еще в качестве возвращаемого значения.

Например: updatePayload := bson.M{...} результат, err := db.[tablename].UpdateByID(ctx.Context, updatedID, bson.M{"$set": updatePayload})

If result.ModifiedCount == 0 { continue // это означает, что ни одно поле не было обновлено. }

Я уверен, что у SQLAlchemy есть и аналогичные функции.

-2
Panda Dev 30 Май 2023 в 21:15
1
Ваш ответ может быть улучшен с помощью дополнительной вспомогательной информации. Пожалуйста, отредактируйте, чтобы добавить дополнительные сведения, такие как цитаты или документация, чтобы другие могли подтвердить правильность вашего ответа. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.
 – 
Community
30 Май 2023 в 21:19
1
Я предполагаю, что OP хочет знать до выполнения операторов.
 – 
snakecharmerb
30 Май 2023 в 21:33