|
# -*- coding: utf-8 -*- |
|
""" |
|
init_flat.py |
|
============ |
|
|
|
This script initializes tables with relational tags. The tables (named |
|
*posts*, *tags* and *posts_to_tags*) will be dropped if necessary. |
|
|
|
Usage |
|
----- |
|
|
|
``python init_relational.py <pgsql_db_url>`` |
|
|
|
The *pgsql_db_url* command line argument should be a SQLAlchemy-compatible |
|
DB URI. |
|
""" |
|
|
|
import codecs |
|
import json |
|
import os |
|
import sys |
|
|
|
from sqlalchemy import Column, ForeignKey, Integer, String, Table, Text,\ |
|
create_engine |
|
from sqlalchemy.ext.declarative import declarative_base |
|
from sqlalchemy.orm import backref, relationship, sessionmaker |
|
|
|
Base = declarative_base() |
|
|
|
post_to_tag = Table( |
|
'posts_to_tags', Base.metadata, |
|
Column('post_id', Integer, ForeignKey('posts.id')), |
|
Column('tag_id', Integer, ForeignKey('tags.id')) |
|
) |
|
|
|
|
|
class Post(Base): |
|
__tablename__ = 'posts' |
|
|
|
id = Column(Integer, primary_key=True) |
|
slug = Column(String(255), unique=True) |
|
title = Column(Text) |
|
|
|
def __repr__(self): |
|
_dict = { |
|
'id': self.id, |
|
'slug': self.slug, |
|
'title': self.title, |
|
'tags': [tag.name for tag in self.tags] |
|
} |
|
|
|
return json.dumps(_dict) |
|
|
|
tags = relationship('Tag', secondary=post_to_tag, backref='posts') |
|
|
|
|
|
class Tag(Base): |
|
__tablename__ = 'tags' |
|
|
|
id = Column(Integer, primary_key=True) |
|
name = Column(String(255), unique=True) |
|
|
|
def __repr__(self): |
|
_dict = { |
|
'id': self.id, |
|
'name': self.name |
|
} |
|
|
|
return json.dumps(_dict) |
|
|
|
if __name__ == '__main__': |
|
if len(sys.argv) == 1: |
|
raise RuntimeError('DB URI not provided') |
|
|
|
if not os.path.isfile('fixture.json'): |
|
raise RuntimeError('fixture.json not found') |
|
|
|
fixture = None |
|
with codecs.open('fixture.json', 'r', 'utf-8') as fixture_file: |
|
fixture = json.loads(fixture_file.read()) |
|
|
|
engine = create_engine(sys.argv[1]) |
|
Session = sessionmaker(bind=engine) |
|
|
|
Base.metadata.drop_all(bind=engine) |
|
Base.metadata.create_all(bind=engine) |
|
|
|
session = Session() |
|
|
|
for tag_fixture in fixture['tags']: |
|
tag = Tag(name=tag_fixture) |
|
session.add(tag) |
|
|
|
session.commit() |
|
|
|
for post_fixture in fixture['posts']: |
|
post = Post( |
|
slug=post_fixture['slug'], |
|
title=post_fixture['title'] |
|
) |
|
|
|
post.tags = session.query(Tag).\ |
|
filter(Tag.name.in_(post_fixture['tags'])).\ |
|
all() |
|
|
|
session.add(post) |
|
|
|
session.commit() |
|
session.close() |