вторник, 26 января 2010 г.

Python + Psycopg2 + Win32 | Ошибка при большом кол-ве подключений к БД

Написав простецкий скрипт на питоне для копирования данных таблицы с MSSQL в PostgreSQL (+ конвертация некоторых полей) напоролся на ошибку - "psycopg.OperationalError, could not connect to server: Address already in use". Запускал скрипт я на Win32, Python2.6, Psycopg2 2.0.13. Долго ковырял гугль. Нашлась тема. И хотя она оказалась решенной ещё в 2006 году - я эту ошибку всё равно получал. Да, библиотека у меня судя по её номеру - намного "новее"...

Помучав мозг и посмотрев на код работы с psql, я увидел, что для вставки каждой строки данных я каждый раз открываю и закрываю соединение... Вот оно! А что, если открыть соединение 1 раз и кидать инсерты? Да, так и быстрее и не получаю ошибку! (вот в фоне уже 80К строк обработано, только нужно учесть, что я соединился с pgBouncer).

Ну или можно вставить time.sleep(3*60) после каждых 2К строк...

четверг, 21 января 2010 г.

Genius NetScroll 220 Laser | Мышь. Понижение чувствительности.

OMG! Все мучался - мышь ЛЕТАЕТ! Оказалось есть переключение dpi (влияет на чувствительность). Знаете как? ХАХА! Нажатием лк+пк+колеса!

УРА!

MSSQL | Подлость. Никогда не доверяйте!

Был обычный день. Настал момент в базе данных у одной таблицы сменить тип с text на ntext. А таблица на 500к строк. И важная - жуть! Ок, Sql managment studio создала скрипт. Интересно, но скрипт создавал временную таблицу, копировал в неё оригинальную, потом дропал оригинальную и переименовывал временную в название оригинала. Вроде - все нормально, все обернуто транзакциями.

Да вот только обернуто то не все вместе, а каждая команда по отдельности! Ну в результате - сначала мешали внешние ключи. А потом просто - оригинальная таблица дропнулась и временной не видно!? ВСЁ!

Прощайте данные!

Да, есть бекап. Ночной. Общий на 50Гиг. Шутки в сторону. Микрософт не научил студию восстанавливать таблицы по одной. Финиш. А точнее - пипец!

Но я умный. У меня есть машина-дублер. Правда она - на постгресе!

В общем поимел я секса с sqlcmd и конвертированием ~300Мегового бекапа в стиле INSERT INTO TABLE. Хорошо что была линукс-машина и хвала vim! Особенно его комманде глобальной замены %s/что_искать/на_что_менять/gn.

Для интереса - sqlcmd работает по стандарту. Т.е. каждая команда должна завершаться пинком командой GO. Но кроме того из-за огромного размера - каждый инсерт пришлось обернуть в транзакцию.

Типа:
begin tran;
insert into ...;
commit tran;
go

Ну и конечно же вызов sqlcmd с флагом кодировки -f 65001 (это utf-8).

Всё. Живем.

пятница, 4 декабря 2009 г.

Werkzeug + SQLAlchemy + Jinja2 + Memcached = Маст трай

Да, да, да! Дошли таки руки! Django отложен в темный ящик, так как мне нужна бОльшая гибкость. Да и админка не нужна совсем в том проекте, который делаю (секрет :-).

Хорошо, что перед встречей с werkzeug я поковырялся с GAE Python (сделал нечто вроде блога). Это помогло мне сделать этакий фреймворк для обработки запросов.
К примеру сделал свой базовый класс Controller. Это объект с response и request классами внутри.

Куски класса:
class Controller():
    def __init__(self, request):
    def get(self): #вызывается при get-запросе
    def post(self): #вызывается при post-запросе
    def render_template(self, template, **context): #так вызывается шаблонизатор
    def preprocess(self): # дергается в конце инициализации. сюда можно навесить декоратор для проверки прав доступа
Кроме того, Controller при каждой инициализации создает в себе объект self.current_user - думаю понятно что это :-)

Еще очень обрадовал шаблонизатор:
- он кэширует шаблоны! (т.е. хранит их в своем пре-компилед виде).
- макросы (можно загружать из файла)

Отдельно помучался с апачем + wsgi. Но как обычно - документация спасает.

П.С.: просто надоел зависающий IIS6

воскресенье, 8 ноября 2009 г.

Cherokee + uWSGI + Django How-To

Навеяно:
http://habrahabr.ru/blogs/python/67475/
http://m.habrahabr.ru/post/70531/
---

Решил тут я попробывать веб-сервер cherokee для django-сайта. Обычно используется flup-прослойка, а я хотел задействовать uwsgi.

Что я сделал (опишу успешные шаги):
1. создал новый django-проект
2. создал новый app "dummy" с простым выводом:
def index(request):
    return HttpResponse('hello from django!')
3. установил cherokee последнюю версию из svn (на сайте чероки описано как это сделать), т.к. в текущей 0.99.19 нет визарда для настройки uWSGI...
4. сайты у меня находятся в каталоге /var/www-cherokee (владелец www-data)
5. в каталог django1 я скопировал свой проект.
6. в /var/www-cherokee нужно поместить uwsgi.xml - это конфигурационный файл для запуска джанго-сайта. содержание моего:
<uwsgi>
    <pythonpath>/var/www-cherokee/</pythonpath>
    <pythonpath>/var/www-cherokee/django1</pythonpath>
    <app mountpoint="/">
        <script>/django1/django_wsgi</script>
    </app>
</uwsgi>
обратите внимание на пути в pythonpath - без них работать не будет.
7. в /var/www-cherokee/django1 помещаем скрипт для вызова джанго (django_wsgi):
#some code for run on cherokee web server

import os
import django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
application = django.core.handlers.wsgi.WSGIHandler()
8. в настройках cherokee (в которые легко попасть через sudo cherokee-admin -u и потом в браузере http://localhost:9090) нужно в разделе "Virtual Server: default" вызвать "wizards"->platforms ->uWSGI ->run wizard.
так же в параметре "Interpreter" проверьте путь до конфига uwsgi.xml (у меня строка выглядит так: /usr/bin/uwsgi -s /tmp/cherokee-source11.sock -C -x /var/www-cherokee/uwsgi.xml )

В принципе - все. Перезапустил сервер и в браузере увидел "hello..."

П.С.: о сломанных копьях в процессе конфигурации я умолчу. если что - я настраивал по этому посту.
П.П.С: если что то не работает (я сначала получал только "uwsgi error" в браузере) - попробуйте запустить в окне терминала строчку из настройки интерпретатора (/usr/bin/uwsgi -s /tmp/cherokee-source11.sock -C -x /var/www-cherokee/uwsgi.xml) и не закрывая его обновить страницу в браузере. потом в терминале можно увидеть ошибки (я так нашел неправильно указанный путь)... ВНИМАНИЕ! после запуска интерпретатора в ручную нужно удалять файл /tmp/cherokee-source11.sock (в моем случае)!

---
тесты:
1. flup
2. uWSGI

= 1 =============
Document Length: 18 bytes

Concurrency Level: 10
Time taken for tests: 102.068 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1660166 bytes
HTML transferred: 180018 bytes
Requests per second: 97.97 [#/sec] (mean)
Time per request: 102.068 [ms] (mean)
Time per request: 10.207 [ms] (mean, across all concurrent requests)
Transfer rate: 15.88 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.8 0 39
Processing: 3 101 241.3 39 3777
Waiting: 0 98 236.6 38 3777
Total: 3 102 241.3 40 3778

Percentage of the requests served within a certain time (ms)
50% 40
66% 56
75% 69
80% 79
90% 171
95% 292
98% 1125
99% 1226
100% 3778 (longest request)

= 2 =============
Document Length: 18 bytes

Concurrency Level: 10
Time taken for tests: 20.044 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1660000 bytes
HTML transferred: 180000 bytes
Requests per second: 498.90 [#/sec] (mean)
Time per request: 20.044 [ms] (mean)
Time per request: 2.004 [ms] (mean, across all concurrent requests)
Transfer rate: 80.88 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.4 0 4
Processing: 3 19 5.4 19 46
Waiting: 3 19 5.3 19 46
Total: 5 20 5.3 19 47

Percentage of the requests served within a certain time (ms)
50% 19
66% 20
75% 22
80% 23
90% 27
95% 30
98% 34
99% 38
100% 47 (longest request)

= результат ======================
flup/uWSGI
Requests per second: 1 к 5
Transfer rate: 1 к 5

В основном 1 к 5!

пятница, 6 ноября 2009 г.

GAE | Свой домен

На текущий момент можно сделать только:
www.ваш_домен.все

Раньше можно было добавить в ДНС-записи А-запись с адресами гугла, но теперь так не сработает. Решение только одно - нужно где-то разместить сайт для домена 2ого уровня и сделать на нем редирект на www.домен. Я пока не искал как проще и за сколько такое сделать - у меня есть где повесить сайт-редирект. Еще вариант - можно купить домен у самого гугла (я не проверял). Или воспользоваться Web-forwarding (у ру-центра он есть).

Я столкнулся с обычной настройкой "своего домена" на app в GAE. Ру-центр. Самое важное - нужно зарегистрироваться в службах Google, так как это единственная возможность привязать свой домен к GAE приложению (я по глупости пытался как "частное лицо" найти решение).
Далее - нужна услуга ДНС-мастер secondary.

Далее всё по гуглу. В службах Google нужно выполнить "подтверждение владением домена". И добавить в ДНС записи:
google_ваша_строка_даст_гугл СNAME google.com.
www CNAME ghs.google.com.

И учтите, что домен должен быть делегирован. Я по малоопытности прождал 2 дня. Потом погуляв по личному кабинету настройки доменов увидел, что нужный мне домен не делегирован...