Ural penguins - Сообщения с тегом PostgreSQLhttp://uralbash.ru/blog/tag/postgresql/atom.xml2014-03-15T17:53:00ZABlogПеренос БД с sqlite на postgreshttp://uralbash.ru/articles/2014/sqlite_to_pg/2014-03-15T17:53:00Z2014-03-15T17:53:00ZUralbash<div class="section" id="sqlite-postgres">
<p><code class="docutils literal"><span class="pre">ORM</span></code> позволяет быстро переключатся между БД не учитывая их диалект
(практически). Но данные хранятся физически в разных местах и естественно их
надо переносить, например при переключении с <a class="reference external" href="http://sqlite.org/">sqlite</a> на <a class="reference external" href="http://postgresql.org">PostgreSQL</a>. В
<a class="reference external" href="https://www.djangoproject.com/">Django</a> есть встроенный функционал в виде:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span><span class="c1"># Выгрузка в JSON</span>
$ python manage.py dumpdata myapp.A > a.json
<span class="c1"># Загрузка из JSON</span>
$ python manage.py loaddata a.json
</pre></div>
</div>
<p>Т.е. мы выгружаем данные из <a class="reference external" href="http://sqlite.org/">sqlite</a> в <code class="docutils literal"><span class="pre">JSON</span></code> формат, затем меняем строку
подключения на <a class="reference external" href="http://postgresql.org">postgres</a> и выполняем загрузку из <code class="docutils literal"><span class="pre">JSON</span></code>. Очень удобно, но
почему то этот метод не работает, либо работает только при переносе из <code class="docutils literal"><span class="pre">sqlite</span>
<span class="pre">-></span> <span class="pre">sqlite</span></code>, что в принципе не очень интересно, точнее бессмысленно. Есть какие
то решений с бубном как это вот:</p>
<div class="line-block">
<div class="line"><a class="reference external" href="http://macrotoma.blogspot.ru/2012/10/solved-move-django-from-sqlite-to-mysql.html">http://macrotoma.blogspot.ru/2012/10/solved-move-django-from-sqlite-to-mysql.html</a>,</div>
<div class="line"><a class="reference external" href="http://blog.abourget.net/2009/7/7/exporting-sql-schemas-from-sqlalchemy-table-definitions/">http://blog.abourget.net/2009/7/7/exporting-sql-schemas-from-sqlalchemy-table-definitions/</a>.</div>
</div>
<p>Эти методы не универсальны, потому что имеют привязку к моделям (ORM), требуют
для переноса проект на <a class="reference external" href="https://www.djangoproject.com/">Django</a> и ручные действия вроде создания схемы и
выполнения миграций (далеко не всегда миграции созданы правильно).</p>
<p>Я написал небольшой пример как можно перевести данные не имея фреймворков, не
привязываясь к моделям, указав только две строки подключения откуда переносить
и куда (вроде было что то похожее на руби). За основы взят пример из этой статьи
<a class="reference external" href="http://www.tylerlesmann.com/2009/apr/27/copying-databases-across-platforms-sqlalchemy/">http://www.tylerlesmann.com/2009/apr/27/copying-databases-across-platforms-sqlalchemy/</a>.
Где предлагается указать дополнительно названия таблиц.</p>
<p>В <a class="reference external" href="http://sqlalchemy.org/">sqlalchemy</a> с весии 9.1 появилась встроенная возможность автоматического
определения схемы БД
<a class="reference external" href="http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html">http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html</a>. Правда
намного раньше появились сторонние решения:</p>
<ul class="simple">
<li><a class="reference external" href="http://turbogears.org/2.1/docs/main/Utilities/sqlautocode.html">http://turbogears.org/2.1/docs/main/Utilities/sqlautocode.html</a></li>
<li><a class="reference external" href="https://sqlsoup.readthedocs.org/en/latest/">https://sqlsoup.readthedocs.org/en/latest/</a>.</li>
</ul>
<p>Первое что мы сделаем, это получим схему БД:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sqlalchemy.ext.automap</span> <span class="kn">import</span> <span class="n">automap_base</span>
<span class="k">def</span> <span class="nf">get_metadata</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">engine</span><span class="p">):</span>
<span class="c1"># produce our own MetaData object</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="n">MetaData</span><span class="p">()</span>
<span class="c1"># we can reflect it ourselves from a database, using options</span>
<span class="c1"># such as 'only' to limit what tables we look at...</span>
<span class="c1"># only = ['news_news', 'pages_page']</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">only</span><span class="p">:</span>
<span class="n">metadata</span><span class="o">.</span><span class="n">reflect</span><span class="p">(</span><span class="n">engine</span><span class="p">,</span> <span class="n">only</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">only</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">metadata</span><span class="o">.</span><span class="n">reflect</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>
<span class="c1"># we can then produce a set of mappings from this MetaData.</span>
<span class="n">Base</span> <span class="o">=</span> <span class="n">automap_base</span><span class="p">(</span><span class="n">metadata</span><span class="o">=</span><span class="n">metadata</span><span class="p">)</span>
<span class="c1"># calling prepare() just sets up mapped classes and relationships.</span>
<span class="n">Base</span><span class="o">.</span><span class="n">prepare</span><span class="p">()</span>
<span class="k">return</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">Base</span>
</pre></div>
</div>
<p>Дальше получаем все таблицы:</p>
<p><code class="docutils literal"><span class="pre">tables</span> <span class="pre">=</span> <span class="pre">Base.classes</span></code></p>
<p>Создаем такую же структуру БД в <a class="reference external" href="http://postgresql.org">postgres</a>:</p>
<p><code class="docutils literal"><span class="pre">metadata.create_all(self.engine_dst)</span></code></p>
<p>По очереди проходим каждую таблицу и переносим из нее данные в новую БД:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="n">tables</span><span class="p">:</span>
<span class="n">columns</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
<span class="k">print</span> <span class="s1">'Transferring records to </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">table</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">name</span>
<span class="k">for</span> <span class="n">record</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">table</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
<span class="n">data</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="p">[(</span><span class="nb">str</span><span class="p">(</span><span class="n">column</span><span class="p">),</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">record</span><span class="p">,</span> <span class="n">column</span><span class="p">))</span> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">]</span>
<span class="p">)</span>
<span class="n">NewRecord</span> <span class="o">=</span> <span class="n">quick_mapper</span><span class="p">(</span><span class="n">table</span><span class="o">.</span><span class="n">__table__</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">session_dst</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">NewRecord</span><span class="p">(</span><span class="o">**</span><span class="n">data</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">session_dst</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</pre></div>
</div>
<p>Если возникли конфликты можно их решить переопределением типов полей. Например
при переносе из <a class="reference external" href="http://sqlite.org/">sqlite</a> в <a class="reference external" href="http://postgresql.org">postgres</a> тип полей <code class="docutils literal"><span class="pre">DATETIME</span></code> нужно
заменить на <code class="docutils literal"><span class="pre">DateTime</span></code>:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">dialect</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">dialect</span><span class="o">.</span><span class="n">name</span>
<span class="n">dialect_dst</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">engine_dst</span><span class="o">.</span><span class="n">dialect</span><span class="o">.</span><span class="n">name</span>
<span class="k">if</span> <span class="n">dialect</span> <span class="o">==</span> <span class="n">dialect_dst</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="p">:</span>
<span class="n">columns</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">c</span>
<span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">:</span>
<span class="k">if</span> <span class="n">dialect_dst</span> <span class="o">==</span> <span class="s1">'postgresql'</span><span class="p">:</span>
<span class="c1"># DATETIME->DateTime</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">column</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="n">DATETIME</span><span class="p">):</span>
<span class="n">column</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">DateTime</span><span class="p">()</span>
</pre></div>
</div>
<p>Пример запуска:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ python convertdbdata.py -f <span class="s2">"sqlite:///fromMydb.sqlite"</span> -t <span class="s2">"postgresql://postgres:postgres@localhost/toMydb"</span> -i <span class="s2">"auth_user,news_news"</span>
</pre></div>
</div>
<p><code class="docutils literal"><span class="pre">-i</span></code> параметр указывает какие таблицы нужно запускать первыми, например в такой ситуации:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>DETAIL: Ключ <span class="o">(</span>user_id<span class="o">)=(</span><span class="m">1</span><span class="o">)</span> отсутствует в таблице <span class="s2">"auth_user"</span>.
<span class="s1">'INSERT INTO django_admin_log (id, action_time, user_id, content_type_id, object_id, object_repr, action_flag,</span>
<span class="s1"> change_message) VALUES (%(id)s, %(action_time)s, %(user_id)s, %(content_type_id)s, %(object_id)s, %(object_repr)s,</span>
<span class="s1"> %(action_flag)s, %(change_message)s)'</span> <span class="o">{</span><span class="s1">'action_flag'</span>: <span class="m">1</span>, <span class="s1">'action_time'</span>: datetime.datetime<span class="o">(</span><span class="m">2014</span>, <span class="m">2</span>, <span class="m">5</span>, <span class="m">13</span>, <span class="m">15</span>, <span class="m">27</span>, <span class="m">948000</span><span class="o">)</span>,
<span class="s1">'user_id'</span>: <span class="m">1</span>, <span class="s1">'content_type_id'</span>: <span class="m">39</span>, <span class="s1">'object_repr'</span>: u<span class="s1">'dfgsdfg'</span>, <span class="s1">'object_id'</span>: u<span class="s1">'1'</span>, <span class="s1">'change_message'</span>: u<span class="s1">''</span>, <span class="s1">'id'</span>: <span class="m">1</span><span class="o">}</span>
</pre></div>
</div>
<p>Код полностью <a class="reference external" href="https://github.com/ITCase/convertdbdata">https://github.com/ITCase/convertdbdata</a></p>
<p>Сейчас скрипт не рассчитан на большие объемы данных и учитывает только разницу
в <code class="docutils literal"><span class="pre">DateTime</span></code> поле, но думаю это легко исправить по мере поступления задач.</p>
</div>
Обновление sacrud и pyramid_exthttp://uralbash.ru/articles/2013/sacrud_release_0_0_3/2013-08-26T16:24:00Z2013-08-26T16:24:00ZUralbash<div class="section" id="sacrud-pyramid-ext">
<p>Новая версия <a class="reference external" href="https://pypi.python.org/pypi/sacrud">sacrud</a> <code class="docutils literal"><span class="pre">0.0.3</span></code>. В ней поправлены некоторые баги,
добавлены <span class="strike">нескучные обои</span> элементы дизайна в расширении для
<code class="docutils literal"><span class="pre">Pyramid</span></code> и создан отдельный репозитарий с примерами работы разных типов
полей (pyramid_sacrud_example). Pyramid_sacrud_example работает только с
<a class="reference external" href="http://postgresql.org">Postgres</a> потому что включает в себя примеры полей специфичных именно для этой
БД (таких как <code class="docutils literal"><span class="pre">hstore</span></code>).</p>
<img alt="_static/2013/sacrud_0_0_3.png" class="align-center" src="_static/2013/sacrud_0_0_3.png" />
</div>
Опиум hstore в plpythonhttp://uralbash.ru/articles/2013/hstore_plpython/2013-07-22T18:17:00Z2013-07-22T18:17:00ZUralbash<div class="section" id="hstore-plpython">
<p>Приведу просто пример триггера на <code class="docutils literal"><span class="pre">plpython</span></code> который использует данные из
поля <code class="docutils literal"><span class="pre">hstore</span></code>:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">TD</span><span class="p">[</span><span class="s2">"event"</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"INSERT"</span><span class="p">,</span> <span class="s2">"UPDATE"</span><span class="p">):</span>
<span class="n">obj_id</span> <span class="o">=</span> <span class="n">TD</span><span class="p">[</span><span class="s2">"new"</span><span class="p">][</span><span class="s2">"id"</span><span class="p">]</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">TD</span><span class="p">[</span><span class="s2">"new"</span><span class="p">][</span><span class="s2">"data"</span><span class="p">]</span>
<span class="n">prepare_data</span> <span class="o">=</span> <span class="n">plpy</span><span class="o">.</span><span class="n">prepare</span><span class="p">(</span><span class="s2">"SELECT hstore($1)->$2 as val;"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"character varying"</span><span class="p">,</span> <span class="s2">"character varying"</span><span class="p">])</span>
<span class="n">param1</span> <span class="o">=</span> <span class="n">plpy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">prepare_data</span><span class="p">,</span> <span class="p">[</span><span class="n">data</span><span class="p">,</span> <span class="s2">"param1"</span><span class="p">])[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'val'</span><span class="p">]</span>
<span class="n">param2</span> <span class="o">=</span> <span class="n">plpy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">prepare_data</span><span class="p">,</span> <span class="p">[</span><span class="n">data</span><span class="p">,</span> <span class="s2">"param2"</span><span class="p">])[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'val'</span><span class="p">]</span>
<span class="n">param3</span> <span class="o">=</span> <span class="n">plpy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">prepare_data</span><span class="p">,</span> <span class="p">[</span><span class="n">data</span><span class="p">,</span> <span class="s2">"param3"</span><span class="p">])[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'val'</span><span class="p">]</span>
<span class="n">param4</span> <span class="o">=</span> <span class="n">plpy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">prepare_data</span><span class="p">,</span> <span class="p">[</span><span class="n">data</span><span class="p">,</span> <span class="s2">"param4"</span><span class="p">])[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'val'</span><span class="p">]</span>
</pre></div>
</div>
<p>Вот так я получаю параметры из <code class="docutils literal"><span class="pre">hstore</span></code>, вместо
<code class="docutils literal"><span class="pre">TD["new"]["data"]["param1"]</span></code>. Может я что то делаю не так?</p>
</div>
Работа с PostgreSQL настройка и масштабированиеhttp://uralbash.ru/articles/2012/pg_book/2012-11-16T14:08:00Z2012-11-16T14:08:00ZUralbash<div class="section" id="postgresql">
<p>Шыкарная книга по <a class="reference external" href="http://postgresql.org">Postgres</a>. Много умных и полезных мыслей в одном месте.
Хорошо написано про репликацию и настройку производительности. Книга на
гитхабе в свободном доступе! Автору лучи добра и счастья, пиши исчо!</p>
<a class="reference external image-reference" href="http://postgresql.leopard.in.ua/"><img alt="_static/2012/pg_book.png" class="align-center" src="_static/2012/pg_book.png" style="width: 400px;" /></a>
</div>
Установка psycopg2 в virtualenv для Postgres 9.1http://uralbash.ru/articles/2011/psycopg2/2011-12-16T18:45:00Z2011-12-16T18:45:00ZUralbash<div class="section" id="psycopg2-virtualenv-postgres-9-1">
<p>При установке <a class="reference external" href="http://initd.org/psycopg/">psycopg</a> в <a class="reference external" href="https://virtualenv.pypa.io/en/latest">virtualenv</a> может возникнуть ошибка:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span><span class="o">(</span>mypythonenv<span class="o">)</span>uralbash@server:~$ pip install psycopg
Downloading/unpacking psycopg
Downloading psycopg2-2.4.3.tar.gz <span class="o">(</span>687Kb<span class="o">)</span>: 687Kb downloaded
Running setup.py egg_info <span class="k">for</span> package psycopg
Error: You need to install postgresql-server-dev-X.Y <span class="k">for</span> building a server-side extension or libpq-dev <span class="k">for</span> building a client-side application.
Complete output from <span class="nb">command</span> python setup.py egg_info:
running egg_info
creating pip-egg-info/psycopg2.egg-info
writing pip-egg-info/psycopg2.egg-info/PKG-INFO
writing top-level names to pip-egg-info/psycopg2.egg-info/top_level.txt
writing dependency_links to pip-egg-info/psycopg2.egg-info/dependency_links.txt
writing manifest file <span class="s1">'pip-egg-info/psycopg2.egg-info/SOURCES.txt'</span>
warning: manifest_maker: standard file <span class="s1">'-c'</span> not found
Error: You need to install postgresql-server-dev-X.Y <span class="k">for</span> building a server-side extension or libpq-dev <span class="k">for</span> building a client-side application.
----------------------------------------
Command python setup.py egg_info failed with error code <span class="m">1</span>
Storing <span class="nb">complete</span> log in /home/uralbash/.pip/pip.log
</pre></div>
</div>
<p>Это возникает из-за утилиты <code class="docutils literal"><span class="pre">pg_config</span></code> которая требуется для установки <a class="reference external" href="http://initd.org/psycopg/">psycopg</a>.
В случае если у Вас <a class="reference external" href="http://postgresql.org">Postgres</a> 8.4 нужно добавить <code class="docutils literal"><span class="pre">pg_config</span></code> в <code class="docutils literal"><span class="pre">PATH</span></code> (как то
так <code class="docutils literal"><span class="pre">PATH=$PATH:/usr/bin/</span></code>). Путь до <code class="docutils literal"><span class="pre">pg_config</span></code> можно узнать:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ whereis pg_config
pg_config: /usr/bin/pg_config
</pre></div>
</div>
<p>И установить пакеты:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo apt-get install libpq-dev python-dev
</pre></div>
</div>
<p>Но если стоит 9.1 версия то может возникнуть ошибка:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or <span class="k">if</span> you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may <span class="nb">help</span> to resolve the situation:
The following packages have unmet dependencies:
libpq-dev : Depends: libpq5 <span class="o">(=</span> <span class="m">8</span>.4.9-0squeeze1<span class="o">)</span> but <span class="m">9</span>.1.1-1~bpo60+1 is to be installed
E: Broken packages
</pre></div>
</div>
<p>В этом случае устанавливаем <a class="reference external" href="http://initd.org/psycopg/">psycopg</a> не в окружении через:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo pip install psycopg2
</pre></div>
</div>
<p>Смотрим куда это встало:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo python -c <span class="s2">"import psycopg2;print psycopg2.__file__"</span>
/usr/lib/python2.6/dist-packages/psycopg2/__init__.pyc
</pre></div>
</div>
<p>И копируем к себе в lib’ы в <a class="reference external" href="https://virtualenv.pypa.io/en/latest">virtualenv</a>:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo cp -r /usr/lib/python2.6/dist-packages/psycopg2 mypythonenv/lib/python2.6/site-packages/
</pre></div>
</div>
<p>Копипастим яйцо:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo cp /usr/lib/python2.6/dist-packages/psycopg2-2.4.4.egg-info mypythonenv/lib/python2.6/site-packages/
</pre></div>
</div>
<p>Еще надо будет скопировать <code class="docutils literal"><span class="pre">mx</span></code>:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo cp -r /usr/lib/python2.6/dist-packages/mx mypythonenv/lib/python2.6/site-packages/
</pre></div>
</div>
<p>Жеский дьютихак но главное что работает малой кровью.</p>
</div>
SQLAlchemy почему PostgreSQL?http://uralbash.ru/articles/2011/sqlalchemy_why_postgres/2011-11-16T00:42:00Z2011-11-16T00:42:00ZUralbash<div class="section" id="sqlalchemy-postgresql">
<p>Потому что я могу делать так:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Net</span><span class="p">)</span>
<span class="n">ip_type</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'ip_type'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
<span class="k">if</span> <span class="n">ip_type</span><span class="o">==</span><span class="s1">'4'</span><span class="p">:</span>
<span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Net</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="s2">"family(cidr)=4"</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">ip_type</span><span class="o">==</span><span class="s1">'6'</span><span class="p">:</span>
<span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Net</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="s2">"family(cidr)=6"</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">nets</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">Net</span><span class="o">.</span><span class="n">cidr</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>
</div>
<p>Здесь если GET переменная <code class="docutils literal"><span class="pre">ip_type=4</span></code> то выбираются все строки где <code class="docutils literal"><span class="pre">cidr</span></code>
IPv4, если 6 то все стоки где <code class="docutils literal"><span class="pre">cidr</span></code> IPv6, иначе просто отдается все. Для
фильтрации используется стандартная функция <a class="reference external" href="http://postgresql.org">Postgres</a> <code class="docutils literal"><span class="pre">family</span></code>. Пример
был так расписан для наглядности, теперь сократим:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Net</span><span class="p">)</span>
<span class="n">ip_type</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'ip_type'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
<span class="k">if</span> <span class="n">ip_type</span><span class="p">:</span>
<span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Net</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="s2">"family(cidr)=</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">ip_type</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">nets</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">nets</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">Net</span><span class="o">.</span><span class="n">cidr</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>
</div>
<p>По моему это просто шЫкарно.</p>
<img alt="_static/2011/awesome.jpeg" src="_static/2011/awesome.jpeg" />
</div>