С базами данных пробую первый раз.
Пытаюсь сделать программку на SQLAlchemy.
Находясь на форуме, придумал тренировочное задание - хранить список тем одной доски форума.
Читаю темы из json-файла:
data.json
[
{
"msg_count": 12, # Количество сообщений в теме.
"number": 7005, # Номер темы на форуме (предполагаю возможность неуникальности, потому не делаю первичным ключом).
"name": "Topic number one.", # Название темы.
"dates": "2011.05.05", # Дата создания (пусть пока в виде строки).
"starter": "knkd" # Топикстартер.
},
{
"msg_count": 21,
"number": 5007,
"name": "Topic number two.",
"dates": "2011.01.01 ",
"starter": "ne_knkd"
},
{
"msg_count": 212,
"number": 5700,
"name": "Topic number three.",
"dates": "2011.09.09 ",
"starter": "ne_knkd_to"
}
]
Всё работает. База создаётся и заполняется значениями.
Хотя способ проверки уникальности номера темы, возможно не самый лучший.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class Topic(Base):
__tablename__ = 'topics'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(128))
starter = Column(String(30))
date = Column(String(30), nullable=True)
number = Column(Integer)
msg_count = Column(Integer)
def __init__(self, data):
self.name = data["name"]
self.starter = data["starter"]
self.date = data["dates"]
self.number = data["number"]
self.msg_count = data["msg_count"]
def __repr__(self):
return "<Topic ({0}, {1}, {2})>".format(self.number,
self.msg_count, self.page_count)
def update(self, topic):
self.name = topic.name
self.starter = topic.starter
self.date = topic.date
self.number = topic.number
self.msg_count = topic.msg_count
def main():
engine = create_engine('sqlite:///./data.sqlite', echo=False)
metadata = Base.metadata
metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
data_list = json.load(open("data.json"))
for topic in data_list:
topic_object = Topic(topic)
dupl = session.query(Topic).filter_by(number=topic["number"]).first()
if dupl == None:
session.add(topic_object)
else:
dupl.update(topic_object)
session.commit()
if __name__ == '__main__':
main()
Вопрос в том - где именно контролировать, есть ли такой пользователь в таблице?
Создавать отдельную функцию со всеми проверками?
Тогда слишком много логики будет за пределами соответствующего класса…
Проверять внутри конструктора класса Topic?
Тогда придётся передавать в конструктор сессию, а правильно ли это?
Может в алхимии это делается как-то по другому?
Код нерабочий, заготовка! (SQL-код создаётся адекватный, но логика не доделана)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(30), nullable=False, primary_key=True)
def __init__(self, user_name):
self.name = user_name
def __repr__(self, name):
return "<User {0}, {1}>".format(self.name, self.id)
class Topic(Base):
__tablename__ = 'topics'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(128))
#starter = Column(String(30))
starter = Column(ForeignKey("users.id"))
date = Column(String(30), nullable=True)
number = Column(Integer)
msg_count = Column(Integer)
def __init__(self, data):
self.name = data["name"]
self.date = data["dates"]
self.number = data["number"]
self.msg_count = data["msg_count"]
#starter = data["starter"]
#user = session.query(User).filter_by(name=starter).first()
def __repr__(self):
return "<Topic ({0}, {1})>".format(self.number, self.starter)
def update(self, topic):
self.name = topic.name
self.starter = topic.starter
self.date = topic.date
self.number = topic.number
self.msg_count = topic.msg_count
def main():
engine = create_engine('sqlite:///data.sqlite', echo=False)
metadata = Base.metadata
metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
data_list = json.load(open("data.json"))
for topic in data_list:
topic_object = Topic(topic)
dupl = session.query(Topic).filter_by(number=topic["number"]).first()
if dupl == None:
session.add(topic_object)
else:
dupl.update(topic_object)
session.commit()
if __name__ == '__main__':
main()