То, как я могу представить SQLAlchemy, привело в действие приложение?

Объяснение различий между OpenID, OAuth, OpenID Connect:

OpenID - это протокол для аутентификации, а OAuth - для авторизации. Аутентификация заключается в том, чтобы убедиться, что парень, с которым вы разговариваете, действительно тот, кем он себя называет. Авторизация - это решение о том, что этому парню разрешено делать.

В OpenID аутентификация делегируется: сервер A хочет аутентифицировать пользователя U, но учетные данные U (например, имя и пароль U) отправляются на другой сервер B, которому A доверяет (по крайней мере, доверяет для аутентификации пользователей). Действительно, сервер B проверяет, действительно ли U является U, и затем говорит A: «Хорошо, это подлинное U».

В OAuth авторизация делегируется: объект A получает от объекта B «право доступа», которое A может показать серверу S для предоставления доступа; Таким образом, B может доставлять временные специальные ключи доступа к A, не давая им слишком много энергии. Вы можете представить себе сервер OAuth в качестве мастера ключей в большом отеле; он дает сотрудникам ключи, которые открывают двери комнат, в которые они должны войти, но каждый ключ ограничен (он не дает доступ ко всем комнатам); кроме того, ключи самоуничтожаются через несколько часов.

В некоторой степени авторизация может быть использована в некоторой псевдо-аутентификации на том основании, что если объект A получает от B ключ доступа через OAuth и показывает его серверу S, то сервер S может сделать вывод, что B аутентифицировал A раньше предоставление ключа доступа. Поэтому некоторые люди используют OAuth там, где они должны использовать OpenID. Эта схема может быть или не быть просветляющей; но я думаю, что эта псевдо-аутентификация более запутана, чем что-либо еще. OpenID Connect делает именно это: он использует OAuth в протокол аутентификации. В аналогии с отелем: если я сталкиваюсь с предполагаемым сотрудником, и этот человек показывает мне, что у него есть ключ, открывающий мою комнату, то я полагаю, что это настоящий сотрудник, поскольку мастер ключей не дал бы ему ключ. который открывает мою комнату, если он не был.

(источник)

Чем OpenID Connect отличается от OpenID 2.0?

OpenID Connect выполняет многие из тех же задач, что и OpenID 2.0 , но делает это способом API, дружественным и используемым в нативных и мобильных приложениях. OpenID Connect определяет дополнительные механизмы для надежной подписи и шифрования. В то время как интеграция OAuth 1.0a и OpenID 2.0 требовала расширения, в OpenID Connect возможности OAuth 2.0 интегрированы с самим протоколом.

(источник)

Соединение OpenID даст вам токен доступа плюс токен id. Идентификационный токен является JWT и содержит информацию об аутентифицированном пользователе. Он подписан поставщиком удостоверений и может быть прочитан и проверен без доступа к поставщику удостоверений.

Кроме того, OpenID connect стандартизирует довольно много вещей, которые oauth2 оставляет на усмотрение. например, области видимости, обнаружение конечной точки и динамическая регистрация клиентов.

Это облегчает написание кода, который позволяет пользователю выбирать между несколькими поставщиками удостоверений.

(источник)

Google OAuth 2.0

API Google OAuth 2.0 можно использовать как для аутентификации, так и для аутентификации. авторизации. Этот документ описывает нашу реализацию OAuth 2.0 для аутентификации, которая соответствует спецификации OpenID Connect и сертифицирована OpenID. Документация, найденная в Использование OAuth 2.0 для доступа к API Google , также применима к этому сервису. Если вы хотите изучить этот протокол в интерактивном режиме, мы рекомендуем Google OAuth 2.0 Playground .

(источник)

47
задан goxe 23 July 2009 в 11:33
поделиться

2 ответа

Иногда простое ведение журнала SQL (включенное через модуль ведения журнала python или через аргумент echo = True в create_engine () ) может дать вам представление как долго все длится. Например, если вы регистрируете что-то сразу после операции SQL, вы увидите в своем журнале что-то вроде этого:

17:37:48,325 INFO  [sqlalchemy.engine.base.Engine.0x...048c] SELECT ...
17:37:48,326 INFO  [sqlalchemy.engine.base.Engine.0x...048c] {<params>}
17:37:48,660 DEBUG [myapp.somemessage] 

если вы зарегистрировали myapp.somemessage сразу после операции, вы знаете, что для завершения потребовалось 334 мс. часть вещей SQL.

Запись в журнал SQL также покажет, выдаются ли десятки / сотни запросов, которые можно было бы лучше организовать в гораздо меньшее количество запросов с помощью соединений. При использовании SQLAlchemy ORM функция "нетерпеливой загрузки" предоставляется частично ( contains_eager () ) или полностью ( eagerload () , eagerload_all () ) автоматизируют эту деятельность, но без ORM это просто означает использование объединений, чтобы результаты из нескольких таблиц могли быть загружены в один набор результатов вместо умножения количества запросов по мере добавления большей глубины (т. Е. r + r * r2 + r * r2 * r3 ...)

Если ведение журнала показывает, что отдельные запросы выполняются слишком долго, вам понадобится разбивка того, сколько времени было потрачено в базе данных обработка запроса, отправка результатов по сети, обработка DBAPI и, наконец, получение набором результатов SQLAlchemy и / или уровнем ORM. На каждом из этих этапов могут быть свои собственные узкие места, в зависимости от специфики.

Для этого вам необходимо использовать профилирование, такое как cProfile или hotshot. Вот декоратор, который я использую:

import cProfile as profiler
import gc, pstats, time

def profile(fn):
    def wrapper(*args, **kw):
        elapsed, stat_loader, result = _profile("foo.txt", fn, *args, **kw)
        stats = stat_loader()
        stats.sort_stats('cumulative')
        stats.print_stats()
        # uncomment this to see who's calling what
        # stats.print_callers()
        return result
    return wrapper

def _profile(filename, fn, *args, **kw):
    load_stats = lambda: pstats.Stats(filename)
    gc.collect()

    began = time.time()
    profiler.runctx('result = fn(*args, **kw)', globals(), locals(),
                    filename=filename)
    ended = time.time()

    return ended - began, load_stats, locals()['result']

Чтобы профилировать секцию кода, поместите ее в функцию с декоратором:

@profile
def go():
    return Session.query(FooClass).filter(FooClass.somevalue==8).all()
myfoos = go()

Результаты профилирования можно использовать, чтобы дать представление о том, на что тратится время. Если, например, вы видите, что все время тратится на cursor.execute () , это вызов DBAPI низкого уровня к базе данных, и это означает, что ваш запрос должен быть оптимизирован, либо путем добавления индексов, либо путем реструктуризации запроса и / или базовая схема. Для этой задачи я бы порекомендовал использовать pgadmin вместе с его графической утилитой EXPLAIN, чтобы увидеть, какую работу выполняет запрос.

Если вы видите много тысяч вызовов, связанных с выборкой строк, это может означать, что ваш запрос возвращает больше строк, чем ожидается - декартово произведение в результате неполного соединения может вызвать эту проблему. Еще одна проблема - время, затрачиваемое на обработку типов - тип SQLAlchemy, такой как Unicode , будет выполнять кодирование / декодирование строк в параметрах связывания и столбцах результатов, что может потребоваться не во всех случаях

. профиль может быть немного сложным, но после некоторой практики их очень легко читать. Однажды в списке рассылки был кто-то, заявляющий о медлительности, и после того, как он опубликовал результаты профиля, я смог продемонстрировать, что проблемы со скоростью были вызваны задержкой в ​​сети - временем, проведенным в cursor.execute (), а также во всем Python. методы были очень быстрыми, тогда как большая часть времени была потрачена на socket.receive ().

Если вы чувствуете амбициозность, есть также более сложный пример профилирования SQLAlchemy в модульных тестах SQLAlchemy, если вы копаетесь http: //www.sqlalchemy. org / trac / browser / sqlalchemy / trunk / test / aaa_profiling . Там у нас есть тесты с использованием декораторов, которые подтверждают максимальное количество вызовов методов, используемых для определенных операций, так что если что-то неэффективное будет проверено, тесты обнаружат это (важно отметить, что в Python вызовы функций имеют наибольшее количество накладные расходы на любую операцию, и количество вызовов чаще всего почти пропорционально затраченному времени). Следует отметить тесты «zoomark», которые используют причудливую схему «захвата SQL», которая исключает накладные расходы на DBAPI из уравнения - хотя эта методика на самом деле не нужна для профилирования садового разнообразия.

у нас есть тесты с использованием декораторов, которые подтверждают максимальное количество вызовов методов, используемых для определенных операций, так что если что-то неэффективное будет проверено, тесты обнаружат это (важно отметить, что в Python вызовы функций имеют самые высокие накладные расходы, чем любая операция, и количество вызовов чаще всего почти пропорционально затраченному времени). Следует отметить тесты «zoomark», которые используют причудливую схему «захвата SQL», которая исключает накладные расходы DBAPI из уравнения - хотя эта методика на самом деле не нужна для профилирования разнообразия садов.

у нас есть тесты с использованием декораторов, которые подтверждают максимальное количество вызовов методов, используемых для определенных операций, так что если что-то неэффективное будет проверено, тесты обнаружат это (важно отметить, что в Python вызовы функций имеют самые высокие накладные расходы, чем любая операция, и количество вызовов чаще всего почти пропорционально затраченному времени). Следует отметить тесты «zoomark», которые используют причудливую схему «захвата SQL», которая исключает накладные расходы DBAPI из уравнения - хотя эта методика на самом деле не нужна для профилирования разнообразия садов.

и количество звонков чаще всего почти пропорционально затраченному времени). Следует отметить тесты «zoomark», которые используют причудливую схему «захвата SQL», которая исключает накладные расходы на DBAPI из уравнения - хотя эта методика на самом деле не нужна для профилирования садового разнообразия.

и количество звонков чаще всего почти пропорционально затраченному времени). Следует отметить тесты «zoomark», которые используют причудливую схему «захвата SQL», которая исключает накладные расходы DBAPI из уравнения - хотя эта методика на самом деле не нужна для профилирования разнообразия садов.

69
ответ дан 26 November 2019 в 19:25
поделиться

Я добился некоторого успеха в использовании cprofile и просмотре результатов в runnakerun. По крайней мере, это рассказало мне, какие функции и вызовы занимают много времени и была ли проблема в базе данных. Документация здесь . Вам нужен wxpython. Его презентация хороша для начала.
Its as easy as

import cProfile
command = """foo.run()"""
cProfile.runctx( command, globals(), locals(), filename="output.profile" )

Then

python runsnake.py output.profile

If you are looking to optimise your queries you will need postgrsql profiling.

It is also worth putting logging on to record the queries, but there is no parser for this that I know of to get the long running queries (and it wont be useful for concurrent requests).

sqlhandler = logging.FileHandler("sql.log")
sqllogger = logging.getLogger('sqlalchemy.engine')
sqllogger.setLevel(logging.info)
sqllogger.addHandler(sqlhandler)

and making sure your create engine statement has echo = True.

When I did it is was actually my code that was the main issue, so the cprofile thing helped.

3
ответ дан 26 November 2019 в 19:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: