|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Приветствую всех! Столкнулся с одной проблемкой при работе с Firebird и с использованием библиотеки питоновской библиотеки fdb. Суть проблемы также описал на стэковерфлове . Продублирую это и здесь. Обратите внимание на код ниже: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Обратите внимание, что все что поменялось - это еще одна подготовленная переменная (prepared variable) после слова ELSE в запросе. Причем, что странно Питон не ругается на аналогичную переменную поле ключевого слова THEN. В чем тут проблема и почему так происходит сам не смог разобраться. Рассчитываю на вашу помощь, форумчане. Мерси! ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 07:30 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
В сервере сломался телепатический модуль и поэтому он не может угадать тип параметров. Делай явный CAST к нужному типу. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 07:49 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Это у вас такой тонкий юмор про телепатический модуль? Согласно по fdb документации никакого явного каста не нужно делать. Да и с точки зрения приложения - это самоубийство. Потому что одно дело везде использовать старые добрые ?, а другое проверять каждую переменную. Значит все-таки я был прав по поводу bullshit? Бага в fdb? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 07:53 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Это у меня такой толстый намек на то, что если из текста запроса совершенно непонятно, какого типа используемые в нем параметры, то надо искать способ их серверу сообщить. Можешь не искать и продолжать считать, что отсутствие телепатических способностей - это баг. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:18 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
А где логика в том, что Код: sql 1.
работает, а Код: sql 1.
не работает? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:24 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Ну а по поводу того, что из запроса совершенно не понятно, какой тип используется. На мой взгляд это понятно из списка параметров, который используется при подготовке запроса: Код: sql 1. 2.
Ну и к тому же документация именно об этом и говорит и не приводит случаев, когда подготовленный запрос должен сработать, а когда - нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:29 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
JacobianНа мой взгляд это понятноНа мой, например, взгляд совершенно непонятно. более того, запихни в первом варианте в параметр строку подлиннее. Повеселело? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:37 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7.
Не вижу проблемы. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:50 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Со строкой в тысячу символов тоже все норм. Так что не вижу повода для веселья. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:53 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
JacobianНу а по поводу того, что из запроса совершенно не понятно, какой тип используется. На мой взгляд это понятно из списка параметров, который используется при подготовке запроса: Кому понятно-то? Питону? Ну, пусть поделится этой информацией с сервером, если умеет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:55 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
JacobianСо строкой в тысячу символов тоже все норм. Так что не вижу повода для веселья. А так? Код: python 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:55 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Тоже все в порядке: Код: sql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:58 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Минуту. Не то сделал. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 08:59 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
JacobianТоже все в порядке: А нефиг мой пример менять, выполняй как есть. Хотя, ты, кажется, не свою проблему хочешь решить, а баг в сервере нарыть. Его там нет, но ты рой. Удачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:00 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
тип параметра в ELSE сервер может предположить по THEN. И наоборот тоже может. Но если и THEN и ELSE оба параметры, то телепатический локатор не способен справиться с задачей. Никакого бага тут нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:10 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Вообще-то у меня такой цели нет. Можешь обратить внимание, что я не констатировал баг, а спрашивал баг ли это. Куда больше меня интересует причина того, что происходит именно так. Я смотрю документацию и вижу в ней одно, а вы даете совершенно другую рекомендацию, противоречащую документации. Вы всячески не обращаете внимание на то, что я даю ссылки на документацию. Вот не ссылка, а цитата: автор Parametrized statements When SQL command you want to execute contains data values, you can either: Embed them directly or via string formatting into command string, e.g.: cur.execute("insert into the_table (a,b,c) values ('aardvark', 1, 0.1)") # or cur.execute("select * from the_table where col == 'aardvark'") # or cur.execute("insert into the_table (a,b,c) values ('%s', %i, %f)" % ('aardvark',1,0.1)) # or cur.execute("select * from the_table where col == '%s'" % 'aardvark') Use parameter marker (?) in command string in the slots where values are expected, then supply those values as Python list or tuple: cur.execute("insert into the_table (a,b,c) values (?,?,?)", ('aardvark', 1, 0.1)) # or cur.execute("select * from the_table where col == ?",('aardvark',)) While both methods have the same results, the second one (called parametrized) has several important advantages: You don’t need to handle conversions from Python data types to strings. FDB will handle all data type conversions (if necessary) from Python data types to Firebird ones, including None/NULL conversion and conversion from unicode to byte strings in encoding expected by server. You may pass BLOB values as open file-like objects, and FDB will handle the transfer of BLOB value. If you’ll pass exactly the same command string again to particular Cursor instance, it will be executed more efficiently (see section about Prepared Statements for details). Parametrized statemets also have some limitations. Currently: DATE, TIME and DATETIME values must be relevant datetime objects. NUMERIC and DECIMAL values must be decimal objects. Обращаю внимание на то, что the second one (called parametrized) has several important advantages и на то, что второй вариант имеет ряд ограничений, но ни одно из них не касается строк. Получается, что документация не актуальна на все сто? Если нет, как бы вы сформулировали в ней тот нюанс, о котором я задал вопрос и объяснили, ПОЧЕМУ в данном случае использование маркера ? не является предпочтительным. К настоящему моменту я просто не услышал солидного аргумента и объяснения (толстые намеки не в счет). ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:15 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Благодарю, dimitr! Теперь все встало на свои места. Хотя подобное поведение удручает, так как в MySQL, SQLite, Postgres, Oracle и MSSQL подобная параметризация запроса работает, как и ожидаешь. Ну и сам вывод типа параметра ELSE по THEN, вы уж меня извините, кроме как бредом я не назову. (IMHO, сугубо субъективно и естественно не претендует на какую-то истину) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:19 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Хотя минутку, dimitr. Как же такой алгоритм вывода типа параметра объясняет ошибку, которая вылетает на последнем примере IBExpert? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:22 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
весь топик не читал, но предположу, что параметр отпрепарировался как CHAR(N), а ты пихаешь в него CHAR(N+X). Что нифига не влазит и генерит ошибку усечения. И это тоже не баг, хотя тоже может показаться непривычным. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:30 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Jacobianвывод типа параметра ELSE по THEN, вы уж меня извините, кроме как бредом я не назову тут не буду спорить :-) Вот только единственная альтернатива - выдавать ошибку и вообще никак не работать. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 09:32 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Jacobianв MySQL, SQLite, Postgres, Oracle и MSSQL подобная параметризация запроса работает, как и ожидаешь. Вышеназванные сервера даже не пытаются определять тип параметра. Поэтому всё и "работает". Но когда ты задашься вопросом "а какой тип совать в параметр и какого размера буфер под него выделять?" всё станет совсем не радужно. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 11:46 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Вышеназванные сервера даже не пытаются определять тип параметра. Вообще-то это не так или во всяком случае не совсем или не всегда так. Если взять тот же Оракл, то он не то что будет пытаться определить тип параметра, но может сделать implicit cast, и выдать ошибку в случае, если типы не совпадают, как, например, в этом случае: [code] select id from test_table WHERE id = :id [code] Если id имеет тип NUMBER, а в качестве параметра передадите какую-нибудь строку, то Оракл попробует привести эту строку к NUMBER и выкинет соответственно ошибку. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 11:57 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
JacobianЕсли id имеет тип NUMBER, а в качестве параметра передадите какую-нибудь строку, то Оракл попробует привести эту строку к NUMBER и выкинет соответственно ошибку. Повторяю медленно: ты не можешь получить от Оракула тип параметра запроса. Вообще. Никак. Ты вынужден отдавать ему те данные, которые у тебя есть и так как они есть. И надеяться, что сервер не дурак и сможет преобразовать их правильно. Что у него получается не каждый раз. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 12:01 |
|
Firebird + Python = bullshit
|
|||
---|---|---|---|
#18+
Еще раз медленно: в том примере, что я привел Оракул (цитата) "пытается определять тип параметра" как NUMBER и выдает ошибку, если в качестве параметра передается какая-нибудь строка. Аналогичный запрос например в MySQL и Postgres уже к ошибке не приводит, потому что они (цитата) "даже не пытаются определять тип параметра". Поэтому то, что ты сказал (в том смысле, как я это понял), не обобщается на все (цитата) "вышеназванные сервера". НО. Я не исключаю, что мог понять этот комментарий не так как следует, и для этого может потребоваться тогда расшифровать что значит (цитата) "получить от ... тип параметра запроса" - можно на примере того же Firebird. А вообще поднятая в топике проблема решена и требует дальнейших объяснений. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2016, 12:22 |
|
|
start [/forum/topic.php?fid=40&msg=39240578&tid=1562169]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
46ms |
get topic data: |
8ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 164ms |
0 / 0 |