Объединение SQLAlchemy yield_per и group_by - PullRequest
0 голосов
/ 24 августа 2018

У меня есть. Таблица базы данных SQLAlchemy, охватывающая 24 часа и имеющая до 1 000 000 строк в час. Пример таблицы ниже.

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declatative_base
from sqlalchemy.orm import sessionmaker
from random import choice

import pandas as pd

Base = declarative_base()


class WebsiteData(Base):
    __tablename__ = 'hourly_website_table'

    id = Column(Integer, primary_key=True)
    user = Column(String(600), index=True)
    website = Column(String(600))
    time_secs = Column(Integer, index=True)

class DataBaseManager:

    def __init__(self, db_loc='sqlite:////home/test/database.db'):
        self.engine = create_engine(db_loc, echo=False)
        self.table = WebsiteData

    def get_session(self):
        Session = sessionmaker(bind=self.engine)
        session = Session()
        Base.metadata.create_all(self.engine)
        return session

    def get_db_info(self):
        session = self.get_session()
        rows = session.query(self.table).count()
        session.close()
        return rows

    def df_to_hourly_db(self, table_name, df, time_secs):
        conn = self.engine.raw_connection()
        df['hour'] = time_secs
        query = "INSERT OR REPLACE INTO %s (user,website,time_secs) VALUES (?,?,?)" %\
            table_name
        conn.executemany(query, df[['user', 'website', 'hour']].to_records(index=False))
        conn.commit()
        conn.close()

def create_df(time_secs=0, users=10000, rows_per_user=100):
    user_arr = [("u%d" % i) for i in range(users)] * rows_per_user
    web_arr = [("www.website_%d" % (time_secs + i)) for i in xrange(rows_per_user * users)]
    return pd.DataFrame({'user': user_arr, 'website': web_arr})

DBM = DataBaseManager()

for hour in range(24):
    time_secs = (60 * 24 * 3600) + (hour * 3600)
    df = create_df(time_secs=time_secs, rows_per_user=choice(range(100)))
    DBM.df_to_hourly_db(df, time_secs)

Количество строк в час является переменным. Чтобы избежать необходимости загружать всю таблицу в память сразу, я хотел бы выполнить group_by(table.time_secs) для данных, а затем последовательно выполнить потоковую передачу каждой группы. Можно ли как-то объединить методы SQLAlchemy group_by и yield_per для достижения этой цели? Я знаю, yield_per позволяет вам выводить заданное количество строк за раз, но возможно ли получить разное количество строк на одну итерацию? Если нет, есть ли другой способ сделать что-то подобное?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...