Monday, 24 May 2021

How to create private teams with sqlalchemy

I am trying to create a slow web game and I am having trouble with my databases. I am a total noob when it comes this area so all help is appreciated.

The details of the mechanics are so far that:

  • Each character can belong to one or many teams.
  • A character can choose an item in the team.
  • Only the team the character picked the item in can see that item.
  • An item has properies like attributes and conditions.

What I am trying to do at this stage is to be able to present the item which the character has picked to the team it was picked in along with the conditions and attributes.

  • Is this possible with how I've organized my tables?
  • If not how should I organize my tables?
  • How would a possible query for selecting the items, the items condition and attributes (grouped) for a certain character in a certain team? (with sqlalchemy)

Any suggestions or solutions are appreciated.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pandas as pd
import logging

logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)


class Config:
    SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:?charset=utf8'
    SQLALCHEMY_DATABASE_ECHO = False
    SQLALCHEMY_TRACK_MODIFICATIONS = 'False'
    FLASK_ENV = 'test'
    DEBUG = True


db = SQLAlchemy()
conf = Config()


def create_app():
    app = Flask(__name__)
    app.config.from_object(conf)
    db.init_app(app)

    return app


def easy_print(p):
    if isinstance(p, list):
        for i in p:
            LOGGER.info(f"{i}")
    else:
        LOGGER.info(f"{p}")
    LOGGER.info(f"--------")


def easy_commit():
    try:
        db.session.commit()
        LOGGER.debug(f'Commit Successfull')
    except Exception as e:
        LOGGER.error(f'Error when committing: {e}')
        db.session.rollback()


# -----------------------Bridge-Tables----------------


itemCharacterAssociation = db.Table(
    'itemCharacterAssociations',
    db.Column('character_id', db.Integer,
              db.ForeignKey('characters.id'),),
    db.Column('item_id', db.Integer,
              db.ForeignKey('items.id'),),
)

itemAssociation = db.Table(
    'itemAssociations',
    db.Column('items_id', db.Integer,
              db.ForeignKey('items.id'),),
    db.Column('itemAttributes_id', db.Integer,
              db.ForeignKey('itemAttributes.id'),),
)
spaceItemsAssociation = db.Table(
    'spaceItemAssociations',
    db.Column('space_id', db.Integer,
              db.ForeignKey('spaces.id'),),
    db.Column('item_id', db.Integer,
              db.ForeignKey('items.id'),),
)

spaceAssociation = db.Table(
    'spaceAssociations',
    db.Column('space_id', db.Integer,
              db.ForeignKey('spaces.id'),),
    db.Column('character_id', db.Integer,
              db.ForeignKey('characters.id'),),
)

# --------------------END-Bridge-Tables---------------


# -----------------------Items-----------------------


class itemAttribute(db.Model):
    __tablename__ = 'itemAttributes'
    id = db.Column(db.Integer, primary_key=True, index=True,)
    category = db.Column(db.String(80),
                         unique=True, nullable=False,)

    def __repr__(self):
        return '{}'.format(self.category)


class Condition(db.Model):
    __tablename__ = 'conditions'
    id = db.Column(db.Integer, db.ForeignKey("items.id"), primary_key=True,)
    condition = db.Column(db.String(4), index=True, nullable=False,)
    items = db.relationship("Item", back_populates="condition",)

    def __repr__(self):
        return '{}'.format(self.condition)


class Item(db.Model):
    __tablename__ = 'items'
    id = db.Column(db.Integer, primary_key=True, index=True,)
    name = db.Column(db.String(80), unique=True, nullable=False,)
    condition = db.relationship("Condition", uselist=False,
                                back_populates="items", cascade="delete",)
    itemAttribute = db.relationship(
        "itemAttribute", secondary="itemAssociations", backref=db.backref("items"),)

    def __repr__(self):
        return '{}'.format(self.name)

# ----------------------END-items-----------------------


# ----------------------Team-stuff----------------------


class Character(db.Model):
    __tablename__ = 'characters'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=False)
    confirmed_bad_ass = db.Column(db.Boolean, nullable=False, default=False,)
    items = db.relationship(
        "Item", secondary="itemCharacterAssociations", backref=db.backref("items"),)

    def __repr__(self):
        return '{}'.format(self.name)


class Space(db.Model):
    __tablename__ = 'spaces'
    id = db.Column(db.Integer, primary_key=True, index=True,)
    name = db.Column(db.String(80), unique=True, nullable=False,)
    members = db.relationship(
        "Character", secondary="spaceAssociations", backref=db.backref("spaces"),)
    items = db.relationship(
        "Item", secondary="spaceItemAssociations", backref=db.backref("spaces"),)

    def __repr__(self):
        return '{}'.format(self.name)

# ----------------------END-Team-stuff------------------


def game():
    LOGGER.info(f"Starting game")
    app = create_app()
    context = app.app_context()
    context.push()
    db.create_all()

# ------------------CONTENT----------------------
    m1 = Item(name="pipe")
    m2 = Item(name="dagger")
    m3 = Item(name="staff")
    m4 = Item(name="documents")
    r1 = Condition(condition="3.5", items=m1)
    r2 = Condition(condition="3.0", items=m2)
    r3 = Condition(condition="4.0", items=m3)
    r4 = Condition(condition="4.3", items=m4)
    i1 = itemAttribute(category="cold")
    i2 = itemAttribute(category="hard")
    i3 = itemAttribute(category="slow")
    i4 = itemAttribute(category="fast")
    i5 = itemAttribute(category="long")
    i6 = itemAttribute(category="soft")
    m1.itemAttribute.append(i1)
    m1.itemAttribute.append(i2)
    m1.itemAttribute.append(i5)
    m2.itemAttribute.append(i4)
    m2.itemAttribute.append(i2)
    m3.itemAttribute.append(i2)
    m4.itemAttribute.append(i6)
    db.session.add_all([m1, m2, m3, r1, r2, r3, r4, i1, i2, i3, i4])
    easy_commit()
    u1 = Character(name='john_the_brave')
    u2 = Character(name='frank_the_punk')
    u3 = Character(name='kyle_the_cunning')
    u4 = Character(name='conan_the_cynic')
    u5 = Character(name='ulrich_the_bland')
    u6 = Character(name='silvana_the_quick')
    u7 = Character(name='sonia_the_magic')
    u8 = Character(name='sarah_the_archer')
    u9 = Character(name='patric_the_indecicive')
    u10 = Character(name='terry_the_writer')
    db.session.add_all([u1, u2, u3, u4, u5, u6, u7, u8, u9, u10])
    easy_commit()
    g1 = Space(name="good_guys")
    g1.members.append(u1)
    g1.members.append(u3)
    g1.members.append(u4)
    g1.members.append(u8)
    g2 = Space(name="bad_guys")
    g2.members.append(u4)
    g2.members.append(u5)
    g2.members.append(u6)
    g2.members.append(u10)
    g2.items.append(m1)
    g3 = Space(name="bandit_guys")
    g3.members.append(u2)
    g3.members.append(u7)
    g3.members.append(u9)
    u3.confirmed_bad_ass = True
    u3.items.append(m1)
    u3.items.append(m2)
    u4.items.append(m3)
    u4.items.append(m4)
    u8.confirmed_bad_ass = True
    u10.confirmed_bad_ass = True
    u10.items.append(m2)
    u10.items.append(m3)
    db.session.add_all([g1, g2, g3, u3, u4, u8, u10])
    easy_commit()
    easy_print(Item.query.all())
    easy_print(Condition.query.all())
    easy_print(itemAttribute.query.all())
    easy_print(g2)
    easy_print(g2.members)
    easy_print(g2.items)

    LOGGER.debug(f"{u1.confirmed_bad_ass}")
# ----------------END-CONTENT--------------------
    context.pop()
    LOGGER.info(f"Ending game")


if __name__ == '__main__':
    game()


from How to create private teams with sqlalchemy

No comments:

Post a Comment