예제 #1
0
def upsert(model, data, update_field, engine):
    """
    upsert实现
    依据session.bind.dialect得到当前数据库类型
    然后生成对应的upsert语句,当前支持mysql,postgresql,sqlite三种数据库
    on_duplicate_key_update for mysql
    on_conflict_do_nothing for postgresql
    insert or ignore for sqlite

    Parameters
    ----------
    model : Base
        orm model
    data : list
    update_field : list
    engine
        _engine.Engine instance
    Returns
    -------
    insert
        insert statement
    """

    if engine.dialect.name == 'mysql':
        stmt = mysql_insert(model).values(data)
        d = {f: getattr(stmt.inserted, f) for f in update_field}
        return stmt.on_duplicate_key_update(**d)
    elif engine.dialect.name == 'postgresql':
        stmt = postgres_insert(model).values(data)
        return stmt.on_conflict_do_nothing(index_elements=[update_field[0]])
    elif engine.dialect.name == 'sqlite':
        stmt = insert(model).values(data).prefix_with('OR IGNORE')
        return stmt
    else:
        raise Exception(f"can't support {engine.dialect.name} dialect")
예제 #2
0
def player_insert_on_conflict_update():
    if Config.db_engine == "mysql":
        query_insert = mysql_insert(scoreboard)
        return query_insert.on_duplicate_key_update(
            name=query_insert.inserted.name,
            team=query_insert.inserted.team,
            alive=query_insert.inserted.alive,
            ping=query_insert.inserted.ping,
            kills=query_insert.inserted.kills,
            headshots=query_insert.inserted.headshots,
            assists=query_insert.inserted.assists,
            deaths=query_insert.inserted.deaths,
            shots_fired=query_insert.inserted.shots_fired,
            shots_hit=query_insert.inserted.shots_hit,
            mvps=query_insert.inserted.mvps,
            score=query_insert.inserted.score,
            disconnected=query_insert.inserted.disconnected)
    elif Config.db_engine == "psycopg2":
        query_insert = postgresql_insert(scoreboard)
        return postgresql_insert(scoreboard).on_conflict_do_update(
            set_=dict(name=query_insert.inserted.name,
                      team=query_insert.inserted.team,
                      alive=query_insert.inserted.alive,
                      ping=query_insert.inserted.ping,
                      kills=query_insert.inserted.kills,
                      headshots=query_insert.inserted.headshots,
                      assists=query_insert.inserted.assists,
                      deaths=query_insert.inserted.deaths,
                      shots_fired=query_insert.inserted.shots_fired,
                      shots_hit=query_insert.inserted.shots_hit,
                      mvps=query_insert.inserted.mvps,
                      score=query_insert.inserted.score,
                      disconnected=query_insert.inserted.disconnected))
    else:
        return scoreboard.insert
예제 #3
0
 async def bind_character_external_id(cls, character_id: int, external_type: ExternalType, external_id: str):
     query = mysql_insert(cls.t).values(
         character_id=character_id,
         type=int(external_type),
         external_id=external_id,
     ).on_duplicate_key_update(
         external_id=external_id,
     )
     await table.execute(query)
예제 #4
0
 async def bind_character_to_campaign(cls, character_id: int, name: str, campaign_id: int):
     query = mysql_insert(cls.t).values(
         character_id=character_id,
         name=name,
         campaign_id=campaign_id,
     ).on_duplicate_key_update(
         name=name,
     )
     await table.execute(query)
예제 #5
0
def on_user_conflict() -> Any:
    """Used for updating a users on conflict.
    """

    if Config.db_engine == "mysql":
        query_insert = mysql_insert(user_table)
        return query_insert.on_duplicate_key_update(
            name=query_insert.inserted.name,
            timestamp=query_insert.inserted.timestamp)
    elif Config.db_engine == "psycopg2":
        query_insert = postgresql_insert(user_table)
        return query_insert.on_conflict_do_update(
            set_=dict(name=query_insert.inserted.name,
                      timestamp=query_insert.inserted.timestamp))
    else:
        return user_table.insert
예제 #6
0
def on_scoreboard_conflict() -> Any:
    """Used for updating a player on a scoreboard on conflict.
    """

    if Config.db_engine == "mysql":
        query_insert = mysql_insert(scoreboard_table)
        return query_insert.on_duplicate_key_update(
            team=query_insert.inserted.team,
            alive=query_insert.inserted.alive,
            ping=query_insert.inserted.ping,
            kills=scoreboard_table.c.kills + query_insert.inserted.kills,
            headshots=scoreboard_table.c.headshots +
            query_insert.inserted.headshots,
            assists=scoreboard_table.c.assists + query_insert.inserted.assists,
            deaths=scoreboard_table.c.deaths + query_insert.inserted.deaths,
            shots_fired=scoreboard_table.c.shots_fired +
            query_insert.inserted.shots_fired,
            shots_hit=scoreboard_table.c.shots_hit +
            query_insert.inserted.shots_hit,
            mvps=scoreboard_table.c.mvps + query_insert.inserted.mvps,
            score=scoreboard_table.c.score + query_insert.inserted.score,
            disconnected=query_insert.inserted.disconnected)
    elif Config.db_engine == "psycopg2":
        query_insert = postgresql_insert(scoreboard_table)
        return query_insert.on_conflict_do_update(
            set_=dict(team=query_insert.inserted.team,
                      alive=query_insert.inserted.alive,
                      ping=query_insert.inserted.ping,
                      kills=scoreboard_table.c.kills +
                      query_insert.inserted.kills,
                      headshots=scoreboard_table.c.headshots +
                      query_insert.inserted.headshots,
                      assists=scoreboard_table.c.assists +
                      query_insert.inserted.assists,
                      deaths=scoreboard_table.c.deaths +
                      query_insert.inserted.deaths,
                      shots_fired=scoreboard_table.c.shots_fired +
                      query_insert.inserted.shots_fired,
                      shots_hit=scoreboard_table.c.shots_hit +
                      query_insert.inserted.shots_hit,
                      mvps=scoreboard_table.c.mvps +
                      query_insert.inserted.mvps,
                      score=scoreboard_table.c.score +
                      query_insert.inserted.score,
                      disconnected=query_insert.inserted.disconnected))
    else:
        return scoreboard_table.insert
예제 #7
0
def create_upsert_mysql(table, record):
    """Creates a statement for inserting the passed record to the passed
    table; if the record already exists, the existing record will be updated.
    This uses MySQL `on_duplicate_key_update` (hence upsert), and that
    why the returned statement is valid only for MySQL tables. Refer to this
    `SqlAlchemy MySQL documentation`_ for more information.

    The created statement is not executed by this function.

    Args:
        table (sqlalchemy.sql.schema.Table): database table metadata.
        record (dict): a data record, corresponding to one row, to be inserted.

    Returns:
        sqlalchemy.sql.dml.Insert: a statement for inserting the passed
        record to the specified table.

    .. _SqlAlchemy MySQL documentation:
       https://docs.sqlalchemy.org/en/latest/dialects/mysql.html#mysql-inser-on-duplicate-key-update
    """
    insert_stmt = mysql_insert(table).values(record)
    return insert_stmt.on_duplicate_key_update(**record)
예제 #8
0
    def put_data(self,
                 key: bytes,
                 value: bytes,
                 is_result: bool = False) -> None:
        key = ensure_bytes(key)
        if self.engine.name == "postgresql":
            from sqlalchemy.dialects.postgresql import insert as pg_insert

            insert_stmt = pg_insert(KV).values(queue=self.name,
                                               key=key,
                                               value=value)
            self.engine.execute(
                insert_stmt.on_conflict_do_update(
                    index_elements=[KV.c.queue, KV.c.key],
                    set_={"value": insert_stmt.excluded.value},
                ))
        elif self.engine.name == "mysql":
            from sqlalchemy.dialects.mysql import insert as mysql_insert

            insert_stmt = mysql_insert(KV).values(queue=self.name,
                                                  key=key,
                                                  value=value)
            self.engine.execute(
                insert_stmt.on_conflict_do_update(
                    value=insert_stmt.inserted.value))
        else:
            with self.engine.begin() as conn:
                exists = conn.execute(
                    self.kvs(select,
                             literal(True)).where(KV.c.key == key)).scalar()
                if exists is None:
                    query = KV.insert().values(queue=self.name,
                                               key=key,
                                               value=value)
                else:
                    query = self.kvs(update).where(KV.c.key == key).values(
                        value=value)
                conn.execute(query)
예제 #9
0
def on_statistic_conflict() -> Any:
    """Used for updating a statistics on conflict.
    """

    if Config.db_engine == "mysql":
        query_insert = mysql_insert(statistic_table)
        return query_insert.on_duplicate_key_update(
            kills=statistic_table.c.kills + query_insert.inserted.kills,
            headshots=statistic_table.c.headshots +
            query_insert.inserted.headshots,
            assists=statistic_table.c.assists + query_insert.inserted.assists,
            deaths=statistic_table.c.deaths + query_insert.inserted.deaths,
            shots_fired=statistic_table.c.shots_fired +
            query_insert.inserted.shots_fired,
            shots_hit=statistic_table.c.shots_hit +
            query_insert.inserted.shots_hit,
            mvps=statistic_table.c.mvps + query_insert.inserted.mvps)
    elif Config.db_engine == "psycopg2":
        query_insert = postgresql_insert(statistic_table)
        return query_insert.on_conflict_do_update(
            set_=dict(kills=statistic_table.c.kills +
                      query_insert.inserted.kills,
                      headshots=statistic_table.c.headshots +
                      query_insert.inserted.headshots,
                      assists=statistic_table.c.assists +
                      query_insert.inserted.assists,
                      deaths=statistic_table.c.deaths +
                      query_insert.inserted.deaths,
                      shots_fired=statistic_table.c.shots_fired +
                      query_insert.inserted.shots_fired,
                      shots_hit=statistic_table.c.shots_hit +
                      query_insert.inserted.shots_hit,
                      mvps=statistic_table.c.mvps +
                      query_insert.inserted.mvps))
    else:
        return statistic_table.insert