Edit on GitHub

tickets_plus.database.models

File for database models.

This file contains the SQLAlchemy models for the database. These models are used to create the database tables and to interact with the database. For more information on SQLAlchemy, please see the docs: https://docs.sqlalchemy.org/en/20/

Typical usage example:
from tickets_plus.database import models
models.Base.metadata.create_all(...)
  1"""File for database models.
  2
  3This file contains the SQLAlchemy models for the database.
  4These models are used to create the database tables and
  5to interact with the database.
  6For more information on SQLAlchemy, please see the docs:
  7https://docs.sqlalchemy.org/en/20/
  8
  9Typical usage example:
 10    ```py
 11    from tickets_plus.database import models
 12    models.Base.metadata.create_all(...)
 13    ```
 14"""
 15# License: EPL-2.0
 16# SPDX-License-Identifier: EPL-2.0
 17# Copyright (c) 2021-present The Tickets+ Contributors
 18# This Source Code may also be made available under the following
 19# Secondary Licenses when the conditions for such availability set forth
 20# in the Eclipse Public License, v. 2.0 are satisfied: GPL-3.0-only OR
 21# If later approved by the Initial Contributor, GPL-3.0-or-later.
 22
 23import datetime
 24from typing import Type
 25
 26import sqlalchemy
 27from sqlalchemy import orm, sql
 28from sqlalchemy.ext import compiler as cmplr
 29
 30_METADATA_OBJ = sqlalchemy.MetaData(schema="tickets_plus")
 31"""The metadata object for the database. Defines the schema."""
 32
 33
 34class UTCnow(sql.expression.FunctionElement):
 35    """Function to get current UTC time
 36
 37    This is used to get the current UTC time database-side.
 38    Once again, read the SQLAlchemy docs for more information.
 39
 40    Attributes:
 41        type: The type of the expression, in this case, a datetime object
 42        inherit_cache: Whether to inherit the cache, in this case, yes
 43    """
 44
 45    type = sqlalchemy.DateTime()
 46    inherit_cache = True
 47
 48
 49@cmplr.compiles(UTCnow, "postgresql")
 50# This is as according to the docs, but pylint doesn't like it
 51# Can't implement this for sqlite because it doesn't time objects
 52# pylint: disable=unused-argument, invalid-name
 53def pg_UTCnow(element, compiler, **kw):
 54    """Compile the utcnow function for postgresql
 55
 56    Please see the SQLAlchemy docs for more information.
 57    This script is based on the example given in the docs.
 58
 59    Args:
 60      element: The element to compile so, in this case, the UTCnow object.
 61      compiler: The Compiled object can be accessed to get information.
 62      **kw: Keyword arguments.
 63
 64    Returns:
 65        The compiled SQL expression.
 66    """
 67    return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
 68
 69
 70class Base(orm.DeclarativeBase):
 71    """Base of SQLAlchemy models
 72
 73    This is the base class for all SQLAlchemy models.
 74    It is used to define the metadata object for the database.
 75    A detailed database schema is available in our docs.
 76    It includes a diagram of the database tables.
 77    Please see the SQLAlchemy docs for more information about
 78    how to use this class.
 79
 80    Attributes:
 81        metadata: The metadata object for the database.
 82    """
 83
 84    metadata = _METADATA_OBJ
 85
 86
 87class Guild(Base):
 88    """General Guild-specific configuration table
 89
 90    This is the general configuration table.
 91    It contains the general configuration for the bot.
 92    This includes the staff team name, the open message,
 93    and the autoclose time.
 94    It also contains the relationships to all other guild-specific tables.
 95
 96    Attributes:
 97        guild_id: The unique discord-provided guild ID.
 98        open_message: The message to send when a staff thread is opened
 99            defaults to "Staff notes for Ticket $channel." and it is
100            limited to 200 characters.
101        staff_team_name: The name of the staff team
102            defaults to "Staff Team" and is limited to 40 characters.
103        first_autoclose: Time since open with no response to auto-close.
104        any_autoclose: Time since last response to auto-close.
105        warn_autoclose: Time to warn user (via DM) after last response.
106        msg_discovery: Whether to allow message discovery
107            defaults to True.
108        strip_buttons: Whether to strip buttons from messages
109            defaults to False.
110        ticket_bots: The relationship to the TicketBot table.
111        tickets: The relationship to the Ticket table.
112        staff_roles: The relationship to the StaffRole table.
113        observers_roles: The relationship to the ObserversRole table.
114        community_roles: The relationship to the CommunityRole table.
115        community_pings: The relationship to the CommunityPing table.
116        members: The relationship to the Member table.
117    """
118
119    __tablename__ = "general_configs"
120    __table_args__ = {
121        "comment": ("Table for general configurations,"
122                    " this is the parent table for all-guild specific tables.")
123    }
124
125    # Simple columns
126    guild_id: orm.Mapped[int] = orm.mapped_column(sqlalchemy.BigInteger(),
127                                                  primary_key=True,
128                                                  comment="Unique discord-provided guild ID")
129    open_message: orm.Mapped[str] = orm.mapped_column(
130        sqlalchemy.String(200),
131        default="Staff notes for Ticket $channel.",
132        nullable=False,
133        comment="Message to send when a staff thread is opened",
134    )
135    staff_team_name: orm.Mapped[str] = orm.mapped_column(
136        sqlalchemy.String(40),
137        default="Staff Team",
138        nullable=False,
139        comment="Name of the staff team",
140    )
141    first_autoclose: orm.Mapped[datetime.timedelta | None] = orm.mapped_column(
142        sqlalchemy.Interval(), nullable=True, comment="Time since open with no response to auto-close")
143    any_autoclose: orm.Mapped[datetime.timedelta | None] = orm.mapped_column(
144        sqlalchemy.Interval(), nullable=True, comment="Time since last response to auto-close")
145    warn_autoclose: orm.Mapped[datetime.timedelta | None] = orm.mapped_column(
146        sqlalchemy.Interval(), nullable=True, comment="Time to warn user (via DM) after last response")
147    support_block: orm.Mapped[int | None] = orm.mapped_column(
148        sqlalchemy.BigInteger(),
149        nullable=True,
150        comment=("Role to apply to users who are blocked from creating tickets"
151                 " Please manually add this role to blacklist users on"
152                 " https://ticketsbot.net/"
153                 " If not set, considered disabled."))
154    helping_block: orm.Mapped[int | None] = orm.mapped_column(
155        sqlalchemy.BigInteger(),
156        nullable=True,
157        comment=("Role to apply to users who are blocked from helping in tickets"
158                 " I would recommend also preventing the users from obtaining"
159                 " any other support roles."
160                 " Using permissions checks in reaction bots."
161                 " If not set, considered disabled."))
162
163    # Toggles
164    msg_discovery: orm.Mapped[bool] = orm.mapped_column(default=True,
165                                                        nullable=False,
166                                                        comment="Whether to allow message discovery")
167    strip_buttons: orm.Mapped[bool] = orm.mapped_column(default=False,
168                                                        nullable=False,
169                                                        comment="Whether to strip buttons from messages")
170    strip_roles: orm.Mapped[bool] = orm.mapped_column(
171        default=False, nullable=False, comment="Whether to strip comsup roles when applying a helping_block")
172    integrated: orm.Mapped[bool] = orm.mapped_column(default=False,
173                                                     nullable=False,
174                                                     comment="Whether the bot is integrated with the main bot")
175    legacy_threads: orm.Mapped[bool] = orm.mapped_column(default=False,
176                                                         nullable=False,
177                                                         comment="Whether the server has legacy threads")
178
179    # Relationships
180    ticket_bots: orm.Mapped[list["TicketBot"]] = orm.relationship(back_populates="guild", lazy="raise")
181    tickets: orm.Mapped[list["Ticket"]] = orm.relationship(back_populates="guild", lazy="raise")
182    staff_roles: orm.Mapped[list["StaffRole"]] = orm.relationship(back_populates="guild", lazy="raise")
183    observers_roles: orm.Mapped[list["ObserversRole"]] = orm.relationship(back_populates="guild", lazy="raise")
184    community_roles: orm.Mapped[list["CommunityRole"]] = orm.relationship(back_populates="guild", lazy="raise")
185    community_pings: orm.Mapped[list["CommunityPing"]] = orm.relationship(back_populates="guild", lazy="raise")
186    members: orm.Mapped[list["Member"]] = orm.relationship(back_populates="guild", lazy="raise")
187    tags: orm.Mapped[list["Tag"]] = orm.relationship(back_populates="guild", lazy="raise")
188    ticket_types: orm.Mapped[list["TicketType"]] = orm.relationship(back_populates="guild", lazy="raise")
189    # Disabled for now gets sqlalchemy confused
190    # pylint: disable=line-too-long
191    # users: orm.Mapped[list["User"]] = orm.relationship(
192    #    secondary="members", back_populates="guilds", lazy="raise", viewonly=True
193    # )
194
195    # SNOWFLAKE PROTOCOL
196    @orm.reconstructor
197    def init_on_load(self):
198        """Initiate snowflake protocol
199
200        This is a snowflake protocol, which is a way to make the guild ID
201        more accessible. To use with discord.py.
202        """
203        self.id = self.guild_id
204
205
206class TicketBot(Base):
207    """Guild-specific Ticket Bot table
208
209    This is the table for the ticket bots.
210    It contains the user ID of the ticket bot.
211    It also contains the relationship to the Guild table.
212    And the foreign key to the guild ID.
213
214    Attributes:
215        user_id: The unique discord-provided user ID
216        guild_id: The unique discord-provided guild ID
217        guild: The relationship to the Guild table
218    """
219
220    __tablename__ = "ticket_bots"
221    __table_args__ = {
222        "comment": ("Users that open the ticket channels, mostly the Tickets bot,"
223                    " but can be other users due to whitelabel options.")
224    }
225
226    # Simple columns
227    user_id: orm.Mapped[int] = orm.mapped_column(
228        sqlalchemy.BigInteger(),
229        nullable=False,
230        comment=("Unique discord-provided user ID."
231                 " Used in conjunction with guild_id to make a unique primary key"),
232        primary_key=True,
233        unique=False,
234    )
235    guild_id: orm.Mapped[int] = orm.mapped_column(
236        sqlalchemy.BigInteger(),
237        sqlalchemy.ForeignKey("general_configs.guild_id"),
238        nullable=False,
239        comment=("Unique Guild ID of parent guild."
240                 " Used in conjunction with user_id to make a unique primary key"),
241        primary_key=True,
242        unique=False,
243    )
244
245    # Relationships
246    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="ticket_bots", lazy="selectin")
247
248
249class TicketType(Base):
250    """Categorize tickets based on the prefix of the channel name
251
252    This is the table for the ticket types.
253    It contains the prefix of the ticket type.
254    It also contains the relationship to the Guild table.
255    And the foreign key to the guild ID.
256    And type-specific setting overrides.
257
258    Attributes:
259        prefix: The prefix of the ticket type. Also, the type name.
260        guild_id: The unique discord-provided guild ID
261        guild: The relationship to the Guild table
262        comping: Whether to ping the community roles when template matches
263        comaccs: Whether to ping the community roles when template matches
264        strpbuttns: Whether to strip buttons from open when template matches
265    """
266
267    __tablename__ = "ticket_types"
268    __table_args__ = {"comment": "Ticket types are stored here. Each guild can have multiple."}
269
270    # Simple columns
271    prefix: orm.Mapped[str] = orm.mapped_column(
272        sqlalchemy.String(20),
273        nullable=False,
274        comment="The prefix of the ticket type",
275        primary_key=True,
276    )
277    guild_id: orm.Mapped[int] = orm.mapped_column(
278        sqlalchemy.BigInteger(),
279        sqlalchemy.ForeignKey("general_configs.guild_id"),
280        nullable=False,
281        comment="The unique discord-provided guild ID",
282        primary_key=True,
283    )
284    comping: orm.Mapped[bool] = orm.mapped_column(default=True,
285                                                  nullable=False,
286                                                  comment="Whether to ping the community roles when template matches")
287    comaccs: orm.Mapped[bool] = orm.mapped_column(default=True,
288                                                  nullable=False,
289                                                  comment="Whether to add the community roles when template matches")
290    strpbuttns: orm.Mapped[bool] = orm.mapped_column(default=True,
291                                                     nullable=False,
292                                                     comment="Whether to strip buttons from open when template matches")
293    ignore: orm.Mapped[bool] = orm.mapped_column(default=False,
294                                                 nullable=False,
295                                                 comment="Whether to ignore this ticket type")
296
297    # Relationships
298    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="ticket_types", lazy="selectin")
299
300    @classmethod
301    def default(cls: Type["TicketType"]) -> "TicketType":
302        """Default ticket type
303
304        This is the default ticket type.
305        It is used when no ticket type is specified.
306        """
307        return cls(prefix="", guild_id=0, comping=True, comaccs=True, strpbuttns=True, ignore=False)
308
309
310class Ticket(Base):
311    """Ticket channels table
312
313    This is the table for the ticket channels.
314    It contains the channel ID of the ticket channel.
315    It also contains the relationship to the Guild table.
316    And the foreign key to the guild ID.
317    Any closed tickets are deleted from this table.
318
319    Attributes:
320        channel_id: The unique discord-provided channel ID.
321        guild_id: The unique discord-provided guild ID.
322        user_id: The unique discord-provided user ID.
323        date_created: The date the ticket was created.
324        last_response: The date of the last response in the ticket.
325        staff_note_thread: The unique discord-provided ID of the note thread.
326        anonymous: Whether the ticket is in anonymous mode.
327        guild: The relationship to the Guild table.
328    """
329
330    __tablename__ = "tickets"
331    __table_args__ = {"comment": "Channels that are tickets are stored here."}
332
333    # Simple columns
334    channel_id: orm.Mapped[int] = orm.mapped_column(sqlalchemy.BigInteger(),
335                                                    primary_key=True,
336                                                    comment="Unique discord-provided channel ID")
337    guild_id: orm.Mapped[int] = orm.mapped_column(
338        sqlalchemy.BigInteger(),
339        sqlalchemy.ForeignKey("general_configs.guild_id"),
340        nullable=False,
341        comment="Unique Guild ID of parent guild",
342    )
343    user_id: orm.Mapped[int | None] = orm.mapped_column(
344        sqlalchemy.BigInteger(),
345        nullable=True,
346        comment="Unique discord-provided user ID",
347    )
348    date_created: orm.Mapped[datetime.datetime] = orm.mapped_column(
349        sqlalchemy.DateTime(),
350        nullable=False,
351        comment="Date the ticket was created",
352        server_default=UTCnow(),
353    )
354    last_response: orm.Mapped[datetime.datetime] = orm.mapped_column(
355        sqlalchemy.DateTime(),
356        nullable=False,
357        comment="Date the ticket was last responded to",
358        server_default=UTCnow(),
359    )
360    staff_note_thread: orm.Mapped[int | None] = orm.mapped_column(
361        sqlalchemy.BigInteger(),
362        nullable=True,
363        comment="Unique discord-provided channel ID of the staff note thread",
364        unique=True,
365    )
366    anonymous: orm.Mapped[bool] = orm.mapped_column(default=False,
367                                                    nullable=False,
368                                                    comment="Whether the ticket is in anonymous mode")
369    notified: orm.Mapped[bool] = orm.mapped_column(default=False,
370                                                   nullable=False,
371                                                   comment="Whether the user has been notified about this ticket")
372
373    # Relationships
374    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="tickets", lazy="selectin")
375
376    # SNOWFLAKE PROTOCOL
377    @orm.reconstructor
378    def init_on_load(self):
379        """Initiate snowflake protocol
380
381        This is a snowflake protocol, which is a way to make the channel ID
382        more accessible. To use with discord.py.
383        """
384        self.id = self.channel_id
385
386
387class Tag(Base):
388    """Tags table.
389
390    Stores the tags for the guild.
391    Tags are used to quickly respond to common questions.
392    Tags are stored in the database, so they can be
393    updated without restarting the bot.
394    Additionally, if additional columns besides "tag" and "content" are added,
395    the tag is automatically interpreted as an embed.
396
397    Attributes:
398        guild_id: The unique discord-provided guild ID.
399        tag_name: The 'key' of the tag.
400        title: The title of the embed.
401        description: The description of the embed.
402        url: The url of the embed.
403        color: The color of the embed.
404        footer: The footer of the embed.
405        image: The image of the embed.
406        thumbnail: The thumbnail of the embed.
407        author: The author of the embed.
408        guild: The relationship to the Guild table.
409    """
410
411    __tablename__ = "tags"
412    __table_args__ = {"comment": "Tags for the guilds."}
413
414    # Simple columns
415    guild_id: orm.Mapped[int] = orm.mapped_column(sqlalchemy.BigInteger(),
416                                                  sqlalchemy.ForeignKey("general_configs.guild_id"),
417                                                  nullable=False,
418                                                  comment="Unique Guild ID of parent guild",
419                                                  primary_key=True)
420    tag_name: orm.Mapped[str] = orm.mapped_column(sqlalchemy.String(32),
421                                                  nullable=False,
422                                                  comment="The 'key' of the tag",
423                                                  primary_key=True)
424    title: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
425                                                      nullable=True,
426                                                      comment="The title of the embed")
427    description: orm.Mapped[str] = orm.mapped_column(sqlalchemy.String(4096),
428                                                     nullable=False,
429                                                     comment="The description of the embed")
430    url: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
431                                                    nullable=True,
432                                                    comment="The url of the embed")
433    color: orm.Mapped[int | None] = orm.mapped_column(sqlalchemy.Integer(),
434                                                      nullable=True,
435                                                      comment="The color of the embed")
436    footer: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(2048),
437                                                       nullable=True,
438                                                       comment="The footer of the embed")
439    image: orm.Mapped[str] = orm.mapped_column(sqlalchemy.String(256), nullable=True, comment="The image of the embed")
440    thumbnail: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
441                                                          nullable=True,
442                                                          comment="The thumbnail of the embed")
443    author: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
444                                                       nullable=True,
445                                                       comment="The author of the embed")
446
447    # Relationships
448    guild: orm.Mapped["Guild"] = orm.relationship(
449        back_populates="tags",
450        lazy="selectin",
451    )
452
453
454class StaffRole(Base):
455    """Staff roles table
456
457    This is the table for the staff roles.
458    It contains the role ID of the staff role.
459    It also contains the relationship to the Guild table.
460    And the foreign key to the guild ID.
461
462    Attributes:
463        role_id: The unique discord-provided role ID.
464        guild_id: The unique discord-provided guild ID.
465        guild: The relationship to the Guild table.
466    """
467
468    __tablename__ = "staff_roles"
469    __table_args__ = {
470        "comment": ("Roles that are allowed to view ticket notes,"
471                    " and have access to staff commands.")
472    }
473
474    # Simple columns
475    role_id: orm.Mapped[int] = orm.mapped_column(
476        sqlalchemy.BigInteger(),
477        primary_key=True,
478        comment=("Unique discord-provided role ID,"
479                 " this is the primary key as it is unique across guilds"),
480    )
481    guild_id: orm.Mapped[int] = orm.mapped_column(
482        sqlalchemy.BigInteger(),
483        sqlalchemy.ForeignKey("general_configs.guild_id"),
484        nullable=False,
485        comment="Unique Guild ID of parent guild",
486    )
487
488    # Relationships
489    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="staff_roles", lazy="selectin")
490
491    # SNOWFLAKE PROTOCOL
492    @orm.reconstructor
493    def init_on_load(self):
494        """Initiate snowflake protocol
495
496        This is a snowflake protocol, which is a way to make the role ID
497        more accessible. To use with discord.py.
498        """
499        self.id = self.role_id
500
501
502class ObserversRole(Base):
503    """Observer roles table
504
505    This is the table for the observer roles.
506    It contains the role ID of the observer role.
507    It also contains the relationship to the Guild table.
508    And the foreign key to the guild ID.
509
510    Attributes:
511        role_id: The unique discord-provided role ID.
512        guild_id: The unique discord-provided guild ID.
513        guild: The relationship to the Guild table.
514    """
515
516    __tablename__ = "observer_roles"
517    __table_args__ = {"comment": "Roles that are automatically added to tickets notes."}
518
519    # Simple columns
520    role_id: orm.Mapped[int] = orm.mapped_column(
521        sqlalchemy.BigInteger(),
522        primary_key=True,
523        comment=("Unique discord-provided role ID,"
524                 " this is the primary key as it is unique across guilds"),
525    )
526    guild_id: orm.Mapped[int] = orm.mapped_column(
527        sqlalchemy.BigInteger(),
528        sqlalchemy.ForeignKey("general_configs.guild_id"),
529        nullable=False,
530        comment="Unique Guild ID of parent guild",
531    )
532
533    # Relationships
534    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="observers_roles", lazy="selectin")
535
536    # SNOWFLAKE PROTOCOL
537    @orm.reconstructor
538    def init_on_load(self):
539        """Initiate snowflake protocol
540
541        This is a snowflake protocol, which is a way to make the role ID
542        more accessible. To use with discord.py.
543        """
544        self.id = self.role_id
545
546
547class CommunityRole(Base):
548    """Community roles table
549
550    This is the table for the community roles.
551    It contains the role ID of the community role.
552    It also contains the relationship to the Guild table.
553    And the foreign key to the guild ID.
554
555    Attributes:
556        role_id: The unique discord-provided role ID.
557        guild_id: The unique discord-provided guild ID.
558        guild: The relationship to the Guild table.
559    """
560
561    __tablename__ = "community_roles"
562    __table_args__ = {"comment": "Roles that are allowed to view tickets, but aren't staff."}
563
564    # Simple columns
565    role_id: orm.Mapped[int] = orm.mapped_column(
566        sqlalchemy.BigInteger(),
567        primary_key=True,
568        comment=("Unique discord-provided role ID,"
569                 " this is the primary key as it is unique across guilds"),
570    )
571    guild_id: orm.Mapped[int] = orm.mapped_column(
572        sqlalchemy.BigInteger(),
573        sqlalchemy.ForeignKey("general_configs.guild_id"),
574        nullable=False,
575        comment="Unique Guild ID of parent guild",
576    )
577
578    # Relationships
579    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="community_roles", lazy="selectin")
580
581    # SNOWFLAKE PROTOCOL
582    @orm.reconstructor
583    def init_on_load(self):
584        """Initiate snowflake protocol
585
586        This is a snowflake protocol, which is a way to make the role ID
587        more accessible. To use with discord.py.
588        """
589        self.id = self.role_id
590
591
592class CommunityPing(Base):
593    """Community pings table
594
595    This is the table for the community pings.
596    It contains the role ID of the community ping role.
597    It also contains the relationship to the Guild table.
598    And the foreign key to the guild ID.
599
600    Attributes:
601        role_id: The unique discord-provided role ID.
602        guild_id: The unique discord-provided guild ID.
603        guild: The relationship to the Guild table.
604    """
605
606    __tablename__ = "community_pings"
607    __table_args__ = {
608        "comment": ("Table for community pings,"
609                    " pinged when a ticket is opened but"
610                    " after adding the community roles.")
611    }
612
613    # Simple columns
614    role_id: orm.Mapped[int] = orm.mapped_column(
615        sqlalchemy.BigInteger(),
616        primary_key=True,
617        comment=("Unique discord-provided role ID,"
618                 " this is the primary key as it is unique across guilds"),
619    )
620    guild_id: orm.Mapped[int] = orm.mapped_column(
621        sqlalchemy.BigInteger(),
622        sqlalchemy.ForeignKey("general_configs.guild_id"),
623        nullable=False,
624        comment="Unique Guild ID of parent guild",
625    )
626
627    # Relationships
628    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="community_pings", lazy="selectin")
629
630    # SNOWFLAKE PROTOCOL
631    @orm.reconstructor
632    def init_on_load(self):
633        """Initiate snowflake protocol
634
635        This is a snowflake protocol, which is a way to make the role ID
636        more accessible. To use with discord.py.
637        """
638        self.id = self.role_id
639
640
641class Member(Base):
642    """Member table
643
644    This is the table for the members.
645    It is an association table between the users and the guilds.
646    It contains the user ID and the guild ID.
647    It also contains a relationship to both the User and Guild tables.
648    It will also contain any bot information about the user.
649
650    Attributes:
651        user_id: The unique discord-provided user ID.
652        guild_id: The unique discord-provided guild ID.
653        user: The relationship to the User table.
654        guild: The relationship to the Guild table.
655    """
656
657    __tablename__ = "members"
658    __table_args__ = {
659        "comment": ("Table for members,"
660                    " this is a combination of a user and a guild,"
661                    " as a user can be in multiple guilds.")
662    }
663
664    # Simple columns
665    user_id: orm.Mapped[int] = orm.mapped_column(
666        sqlalchemy.BigInteger(),
667        sqlalchemy.ForeignKey("users.user_id"),
668        nullable=False,
669        comment=("Unique discord-provided user ID."
670                 " Used in conjunction with guild_id to make a unique primary key"),
671        primary_key=True,
672        unique=False,
673    )
674    guild_id: orm.Mapped[int] = orm.mapped_column(
675        sqlalchemy.BigInteger(),
676        sqlalchemy.ForeignKey("general_configs.guild_id"),
677        nullable=False,
678        comment=("Unique Guild ID of parent guild."
679                 " Used in conjunction with user_id to make a unique primary key"),
680        primary_key=True,
681        unique=False,
682    )
683    status: orm.Mapped[int] = orm.mapped_column(
684        sqlalchemy.Integer(),
685        nullable=False,
686        default=0,
687        comment=("The status of the member, 0 is normal, "
688                 "1 is support-blocked, 2 is barred from providing support"),
689    )
690    status_till: orm.Mapped[datetime.datetime | None] = orm.mapped_column(
691        sqlalchemy.DateTime(),
692        nullable=True,
693        comment=("The time until the status is removed, "
694                 "if None, the status is permanent"),
695        default=None)
696
697    # Relationships
698    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="members", lazy="selectin")
699    user: orm.Mapped["User"] = orm.relationship(back_populates="memberships", lazy="selectin")
700
701
702class User(Base):
703    """User table
704
705    This is the table for the users.
706    It contains the user ID.
707    It also contains a relationship to the Member table.
708    It will also contain any bot information about the user.
709
710    Attributes:
711        user_id: The unique discord-provided user ID.
712        memberships: The relationship to the Member table.
713        is_owner: Is the user the owner of the bot?
714    """
715
716    __tablename__ = "users"
717    __table_args__ = {
718        "comment": ("Table for users,"
719                    " this is not a guild-specific table,"
720                    " as a user can be in multiple guilds.")
721    }
722
723    # Simple columns
724    user_id: orm.Mapped[int] = orm.mapped_column(
725        sqlalchemy.BigInteger(),
726        primary_key=True,
727        comment=("Unique discord-provided user ID,"
728                 " this is the primary key as it is unique across guilds"),
729    )
730
731    # Toggles
732    is_owner: orm.Mapped[bool] = orm.mapped_column(default=False, comment="Is the user the owner of the bot?")
733
734    # Relationships
735    memberships: orm.Mapped[list["Member"]] = orm.relationship(back_populates="user", lazy="raise")
736    # Disabled for now gets sqlalchemy confused
737    # pylint: disable=line-too-long
738    # guilds: orm.Mapped[list["Guild"]] = orm.relationship(
739    #    secondary="members", back_populates="users", lazy="raise", viewonly=True
740    # )
741
742    # SNOWFLAKE PROTOCOL
743    @orm.reconstructor
744    def init_on_load(self):
745        """Initiate snowflake protocol
746
747        This is a snowflake protocol, which is a way to make the user ID
748        more accessible. To use with discord.py.
749        """
750        self.id = self.user_id
class UTCnow(sqlalchemy.sql.base.Executable, sqlalchemy.sql.elements.ColumnElement[~_T], sqlalchemy.sql.selectable.FromClause, sqlalchemy.sql.base.Generative):
35class UTCnow(sql.expression.FunctionElement):
36    """Function to get current UTC time
37
38    This is used to get the current UTC time database-side.
39    Once again, read the SQLAlchemy docs for more information.
40
41    Attributes:
42        type: The type of the expression, in this case, a datetime object
43        inherit_cache: Whether to inherit the cache, in this case, yes
44    """
45
46    type = sqlalchemy.DateTime()
47    inherit_cache = True

Function to get current UTC time

This is used to get the current UTC time database-side. Once again, read the SQLAlchemy docs for more information.

Attributes:
  • type: The type of the expression, in this case, a datetime object
  • inherit_cache: Whether to inherit the cache, in this case, yes
type = DateTime()
inherit_cache = True

Indicate if this .HasCacheKey instance should make use of the cache key generation scheme used by its immediate superclass.

The attribute defaults to None, which indicates that a construct has not yet taken into account whether or not its appropriate for it to participate in caching; this is functionally equivalent to setting the value to False, except that a warning is also emitted.

This flag can be set to True on a particular class, if the SQL that corresponds to the object does not change based on attributes which are local to this class, and not its superclass.

seealso:

defined SQL constructs.

@cmplr.compiles(UTCnow, 'postgresql')
def pg_UTCnow(element, compiler, **kw):
50@cmplr.compiles(UTCnow, "postgresql")
51# This is as according to the docs, but pylint doesn't like it
52# Can't implement this for sqlite because it doesn't time objects
53# pylint: disable=unused-argument, invalid-name
54def pg_UTCnow(element, compiler, **kw):
55    """Compile the utcnow function for postgresql
56
57    Please see the SQLAlchemy docs for more information.
58    This script is based on the example given in the docs.
59
60    Args:
61      element: The element to compile so, in this case, the UTCnow object.
62      compiler: The Compiled object can be accessed to get information.
63      **kw: Keyword arguments.
64
65    Returns:
66        The compiled SQL expression.
67    """
68    return "TIMEZONE('utc', CURRENT_TIMESTAMP)"

Compile the utcnow function for postgresql

Please see the SQLAlchemy docs for more information. This script is based on the example given in the docs.

Arguments:
  • element: The element to compile so, in this case, the UTCnow object.
  • compiler: The Compiled object can be accessed to get information.
  • **kw: Keyword arguments.
Returns:

The compiled SQL expression.

class Base(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
71class Base(orm.DeclarativeBase):
72    """Base of SQLAlchemy models
73
74    This is the base class for all SQLAlchemy models.
75    It is used to define the metadata object for the database.
76    A detailed database schema is available in our docs.
77    It includes a diagram of the database tables.
78    Please see the SQLAlchemy docs for more information about
79    how to use this class.
80
81    Attributes:
82        metadata: The metadata object for the database.
83    """
84
85    metadata = _METADATA_OBJ

Base of SQLAlchemy models

This is the base class for all SQLAlchemy models. It is used to define the metadata object for the database. A detailed database schema is available in our docs. It includes a diagram of the database tables. Please see the SQLAlchemy docs for more information about how to use this class.

Attributes:
  • metadata: The metadata object for the database.
Base(**kwargs: Any)
2167def _declarative_constructor(self: Any, **kwargs: Any) -> None:
2168    """A simple constructor that allows initialization from kwargs.
2169
2170    Sets attributes on the constructed instance using the names and
2171    values in ``kwargs``.
2172
2173    Only keys that are present as
2174    attributes of the instance's class are allowed. These could be,
2175    for example, any mapped columns or relationships.
2176    """
2177    cls_ = type(self)
2178    for k in kwargs:
2179        if not hasattr(cls_, k):
2180            raise TypeError(
2181                "%r is an invalid keyword argument for %s" % (k, cls_.__name__)
2182            )
2183        setattr(self, k, kwargs[k])

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

metadata = MetaData()
registry = <sqlalchemy.orm.decl_api.registry object>
class Guild(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
 88class Guild(Base):
 89    """General Guild-specific configuration table
 90
 91    This is the general configuration table.
 92    It contains the general configuration for the bot.
 93    This includes the staff team name, the open message,
 94    and the autoclose time.
 95    It also contains the relationships to all other guild-specific tables.
 96
 97    Attributes:
 98        guild_id: The unique discord-provided guild ID.
 99        open_message: The message to send when a staff thread is opened
100            defaults to "Staff notes for Ticket $channel." and it is
101            limited to 200 characters.
102        staff_team_name: The name of the staff team
103            defaults to "Staff Team" and is limited to 40 characters.
104        first_autoclose: Time since open with no response to auto-close.
105        any_autoclose: Time since last response to auto-close.
106        warn_autoclose: Time to warn user (via DM) after last response.
107        msg_discovery: Whether to allow message discovery
108            defaults to True.
109        strip_buttons: Whether to strip buttons from messages
110            defaults to False.
111        ticket_bots: The relationship to the TicketBot table.
112        tickets: The relationship to the Ticket table.
113        staff_roles: The relationship to the StaffRole table.
114        observers_roles: The relationship to the ObserversRole table.
115        community_roles: The relationship to the CommunityRole table.
116        community_pings: The relationship to the CommunityPing table.
117        members: The relationship to the Member table.
118    """
119
120    __tablename__ = "general_configs"
121    __table_args__ = {
122        "comment": ("Table for general configurations,"
123                    " this is the parent table for all-guild specific tables.")
124    }
125
126    # Simple columns
127    guild_id: orm.Mapped[int] = orm.mapped_column(sqlalchemy.BigInteger(),
128                                                  primary_key=True,
129                                                  comment="Unique discord-provided guild ID")
130    open_message: orm.Mapped[str] = orm.mapped_column(
131        sqlalchemy.String(200),
132        default="Staff notes for Ticket $channel.",
133        nullable=False,
134        comment="Message to send when a staff thread is opened",
135    )
136    staff_team_name: orm.Mapped[str] = orm.mapped_column(
137        sqlalchemy.String(40),
138        default="Staff Team",
139        nullable=False,
140        comment="Name of the staff team",
141    )
142    first_autoclose: orm.Mapped[datetime.timedelta | None] = orm.mapped_column(
143        sqlalchemy.Interval(), nullable=True, comment="Time since open with no response to auto-close")
144    any_autoclose: orm.Mapped[datetime.timedelta | None] = orm.mapped_column(
145        sqlalchemy.Interval(), nullable=True, comment="Time since last response to auto-close")
146    warn_autoclose: orm.Mapped[datetime.timedelta | None] = orm.mapped_column(
147        sqlalchemy.Interval(), nullable=True, comment="Time to warn user (via DM) after last response")
148    support_block: orm.Mapped[int | None] = orm.mapped_column(
149        sqlalchemy.BigInteger(),
150        nullable=True,
151        comment=("Role to apply to users who are blocked from creating tickets"
152                 " Please manually add this role to blacklist users on"
153                 " https://ticketsbot.net/"
154                 " If not set, considered disabled."))
155    helping_block: orm.Mapped[int | None] = orm.mapped_column(
156        sqlalchemy.BigInteger(),
157        nullable=True,
158        comment=("Role to apply to users who are blocked from helping in tickets"
159                 " I would recommend also preventing the users from obtaining"
160                 " any other support roles."
161                 " Using permissions checks in reaction bots."
162                 " If not set, considered disabled."))
163
164    # Toggles
165    msg_discovery: orm.Mapped[bool] = orm.mapped_column(default=True,
166                                                        nullable=False,
167                                                        comment="Whether to allow message discovery")
168    strip_buttons: orm.Mapped[bool] = orm.mapped_column(default=False,
169                                                        nullable=False,
170                                                        comment="Whether to strip buttons from messages")
171    strip_roles: orm.Mapped[bool] = orm.mapped_column(
172        default=False, nullable=False, comment="Whether to strip comsup roles when applying a helping_block")
173    integrated: orm.Mapped[bool] = orm.mapped_column(default=False,
174                                                     nullable=False,
175                                                     comment="Whether the bot is integrated with the main bot")
176    legacy_threads: orm.Mapped[bool] = orm.mapped_column(default=False,
177                                                         nullable=False,
178                                                         comment="Whether the server has legacy threads")
179
180    # Relationships
181    ticket_bots: orm.Mapped[list["TicketBot"]] = orm.relationship(back_populates="guild", lazy="raise")
182    tickets: orm.Mapped[list["Ticket"]] = orm.relationship(back_populates="guild", lazy="raise")
183    staff_roles: orm.Mapped[list["StaffRole"]] = orm.relationship(back_populates="guild", lazy="raise")
184    observers_roles: orm.Mapped[list["ObserversRole"]] = orm.relationship(back_populates="guild", lazy="raise")
185    community_roles: orm.Mapped[list["CommunityRole"]] = orm.relationship(back_populates="guild", lazy="raise")
186    community_pings: orm.Mapped[list["CommunityPing"]] = orm.relationship(back_populates="guild", lazy="raise")
187    members: orm.Mapped[list["Member"]] = orm.relationship(back_populates="guild", lazy="raise")
188    tags: orm.Mapped[list["Tag"]] = orm.relationship(back_populates="guild", lazy="raise")
189    ticket_types: orm.Mapped[list["TicketType"]] = orm.relationship(back_populates="guild", lazy="raise")
190    # Disabled for now gets sqlalchemy confused
191    # pylint: disable=line-too-long
192    # users: orm.Mapped[list["User"]] = orm.relationship(
193    #    secondary="members", back_populates="guilds", lazy="raise", viewonly=True
194    # )
195
196    # SNOWFLAKE PROTOCOL
197    @orm.reconstructor
198    def init_on_load(self):
199        """Initiate snowflake protocol
200
201        This is a snowflake protocol, which is a way to make the guild ID
202        more accessible. To use with discord.py.
203        """
204        self.id = self.guild_id

General Guild-specific configuration table

This is the general configuration table. It contains the general configuration for the bot. This includes the staff team name, the open message, and the autoclose time. It also contains the relationships to all other guild-specific tables.

Attributes:
  • guild_id: The unique discord-provided guild ID.
  • open_message: The message to send when a staff thread is opened defaults to "Staff notes for Ticket $channel." and it is limited to 200 characters.
  • staff_team_name: The name of the staff team defaults to "Staff Team" and is limited to 40 characters.
  • first_autoclose: Time since open with no response to auto-close.
  • any_autoclose: Time since last response to auto-close.
  • warn_autoclose: Time to warn user (via DM) after last response.
  • msg_discovery: Whether to allow message discovery defaults to True.
  • strip_buttons: Whether to strip buttons from messages defaults to False.
  • ticket_bots: The relationship to the TicketBot table.
  • tickets: The relationship to the Ticket table.
  • staff_roles: The relationship to the StaffRole table.
  • observers_roles: The relationship to the ObserversRole table.
  • community_roles: The relationship to the CommunityRole table.
  • community_pings: The relationship to the CommunityPing table.
  • members: The relationship to the Member table.
Guild(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

guild_id: sqlalchemy.orm.base.Mapped[int]
open_message: sqlalchemy.orm.base.Mapped[str]
staff_team_name: sqlalchemy.orm.base.Mapped[str]
first_autoclose: sqlalchemy.orm.base.Mapped[datetime.timedelta | None]
any_autoclose: sqlalchemy.orm.base.Mapped[datetime.timedelta | None]
warn_autoclose: sqlalchemy.orm.base.Mapped[datetime.timedelta | None]
support_block: sqlalchemy.orm.base.Mapped[int | None]
helping_block: sqlalchemy.orm.base.Mapped[int | None]
msg_discovery: sqlalchemy.orm.base.Mapped[bool]
strip_buttons: sqlalchemy.orm.base.Mapped[bool]
strip_roles: sqlalchemy.orm.base.Mapped[bool]
integrated: sqlalchemy.orm.base.Mapped[bool]
legacy_threads: sqlalchemy.orm.base.Mapped[bool]
ticket_bots: sqlalchemy.orm.base.Mapped[list[TicketBot]]
tickets: sqlalchemy.orm.base.Mapped[list[Ticket]]
staff_roles: sqlalchemy.orm.base.Mapped[list[StaffRole]]
observers_roles: sqlalchemy.orm.base.Mapped[list[ObserversRole]]
community_roles: sqlalchemy.orm.base.Mapped[list[CommunityRole]]
community_pings: sqlalchemy.orm.base.Mapped[list[CommunityPing]]
members: sqlalchemy.orm.base.Mapped[list[Member]]
tags: sqlalchemy.orm.base.Mapped[list[Tag]]
ticket_types: sqlalchemy.orm.base.Mapped[list[TicketType]]
@orm.reconstructor
def init_on_load(self):
197    @orm.reconstructor
198    def init_on_load(self):
199        """Initiate snowflake protocol
200
201        This is a snowflake protocol, which is a way to make the guild ID
202        more accessible. To use with discord.py.
203        """
204        self.id = self.guild_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the guild ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry
class TicketBot(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
207class TicketBot(Base):
208    """Guild-specific Ticket Bot table
209
210    This is the table for the ticket bots.
211    It contains the user ID of the ticket bot.
212    It also contains the relationship to the Guild table.
213    And the foreign key to the guild ID.
214
215    Attributes:
216        user_id: The unique discord-provided user ID
217        guild_id: The unique discord-provided guild ID
218        guild: The relationship to the Guild table
219    """
220
221    __tablename__ = "ticket_bots"
222    __table_args__ = {
223        "comment": ("Users that open the ticket channels, mostly the Tickets bot,"
224                    " but can be other users due to whitelabel options.")
225    }
226
227    # Simple columns
228    user_id: orm.Mapped[int] = orm.mapped_column(
229        sqlalchemy.BigInteger(),
230        nullable=False,
231        comment=("Unique discord-provided user ID."
232                 " Used in conjunction with guild_id to make a unique primary key"),
233        primary_key=True,
234        unique=False,
235    )
236    guild_id: orm.Mapped[int] = orm.mapped_column(
237        sqlalchemy.BigInteger(),
238        sqlalchemy.ForeignKey("general_configs.guild_id"),
239        nullable=False,
240        comment=("Unique Guild ID of parent guild."
241                 " Used in conjunction with user_id to make a unique primary key"),
242        primary_key=True,
243        unique=False,
244    )
245
246    # Relationships
247    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="ticket_bots", lazy="selectin")

Guild-specific Ticket Bot table

This is the table for the ticket bots. It contains the user ID of the ticket bot. It also contains the relationship to the Guild table. And the foreign key to the guild ID.

Attributes:
  • user_id: The unique discord-provided user ID
  • guild_id: The unique discord-provided guild ID
  • guild: The relationship to the Guild table
TicketBot(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

user_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
guild: sqlalchemy.orm.base.Mapped[Guild]
Inherited Members
Base
metadata
registry
class TicketType(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
250class TicketType(Base):
251    """Categorize tickets based on the prefix of the channel name
252
253    This is the table for the ticket types.
254    It contains the prefix of the ticket type.
255    It also contains the relationship to the Guild table.
256    And the foreign key to the guild ID.
257    And type-specific setting overrides.
258
259    Attributes:
260        prefix: The prefix of the ticket type. Also, the type name.
261        guild_id: The unique discord-provided guild ID
262        guild: The relationship to the Guild table
263        comping: Whether to ping the community roles when template matches
264        comaccs: Whether to ping the community roles when template matches
265        strpbuttns: Whether to strip buttons from open when template matches
266    """
267
268    __tablename__ = "ticket_types"
269    __table_args__ = {"comment": "Ticket types are stored here. Each guild can have multiple."}
270
271    # Simple columns
272    prefix: orm.Mapped[str] = orm.mapped_column(
273        sqlalchemy.String(20),
274        nullable=False,
275        comment="The prefix of the ticket type",
276        primary_key=True,
277    )
278    guild_id: orm.Mapped[int] = orm.mapped_column(
279        sqlalchemy.BigInteger(),
280        sqlalchemy.ForeignKey("general_configs.guild_id"),
281        nullable=False,
282        comment="The unique discord-provided guild ID",
283        primary_key=True,
284    )
285    comping: orm.Mapped[bool] = orm.mapped_column(default=True,
286                                                  nullable=False,
287                                                  comment="Whether to ping the community roles when template matches")
288    comaccs: orm.Mapped[bool] = orm.mapped_column(default=True,
289                                                  nullable=False,
290                                                  comment="Whether to add the community roles when template matches")
291    strpbuttns: orm.Mapped[bool] = orm.mapped_column(default=True,
292                                                     nullable=False,
293                                                     comment="Whether to strip buttons from open when template matches")
294    ignore: orm.Mapped[bool] = orm.mapped_column(default=False,
295                                                 nullable=False,
296                                                 comment="Whether to ignore this ticket type")
297
298    # Relationships
299    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="ticket_types", lazy="selectin")
300
301    @classmethod
302    def default(cls: Type["TicketType"]) -> "TicketType":
303        """Default ticket type
304
305        This is the default ticket type.
306        It is used when no ticket type is specified.
307        """
308        return cls(prefix="", guild_id=0, comping=True, comaccs=True, strpbuttns=True, ignore=False)

Categorize tickets based on the prefix of the channel name

This is the table for the ticket types. It contains the prefix of the ticket type. It also contains the relationship to the Guild table. And the foreign key to the guild ID. And type-specific setting overrides.

Attributes:
  • prefix: The prefix of the ticket type. Also, the type name.
  • guild_id: The unique discord-provided guild ID
  • guild: The relationship to the Guild table
  • comping: Whether to ping the community roles when template matches
  • comaccs: Whether to ping the community roles when template matches
  • strpbuttns: Whether to strip buttons from open when template matches
TicketType(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

prefix: sqlalchemy.orm.base.Mapped[str]
guild_id: sqlalchemy.orm.base.Mapped[int]
comping: sqlalchemy.orm.base.Mapped[bool]
comaccs: sqlalchemy.orm.base.Mapped[bool]
strpbuttns: sqlalchemy.orm.base.Mapped[bool]
ignore: sqlalchemy.orm.base.Mapped[bool]
guild: sqlalchemy.orm.base.Mapped[Guild]
@classmethod
def default( cls: Type[TicketType]) -> TicketType:
301    @classmethod
302    def default(cls: Type["TicketType"]) -> "TicketType":
303        """Default ticket type
304
305        This is the default ticket type.
306        It is used when no ticket type is specified.
307        """
308        return cls(prefix="", guild_id=0, comping=True, comaccs=True, strpbuttns=True, ignore=False)

Default ticket type

This is the default ticket type. It is used when no ticket type is specified.

Inherited Members
Base
metadata
registry
class Ticket(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
311class Ticket(Base):
312    """Ticket channels table
313
314    This is the table for the ticket channels.
315    It contains the channel ID of the ticket channel.
316    It also contains the relationship to the Guild table.
317    And the foreign key to the guild ID.
318    Any closed tickets are deleted from this table.
319
320    Attributes:
321        channel_id: The unique discord-provided channel ID.
322        guild_id: The unique discord-provided guild ID.
323        user_id: The unique discord-provided user ID.
324        date_created: The date the ticket was created.
325        last_response: The date of the last response in the ticket.
326        staff_note_thread: The unique discord-provided ID of the note thread.
327        anonymous: Whether the ticket is in anonymous mode.
328        guild: The relationship to the Guild table.
329    """
330
331    __tablename__ = "tickets"
332    __table_args__ = {"comment": "Channels that are tickets are stored here."}
333
334    # Simple columns
335    channel_id: orm.Mapped[int] = orm.mapped_column(sqlalchemy.BigInteger(),
336                                                    primary_key=True,
337                                                    comment="Unique discord-provided channel ID")
338    guild_id: orm.Mapped[int] = orm.mapped_column(
339        sqlalchemy.BigInteger(),
340        sqlalchemy.ForeignKey("general_configs.guild_id"),
341        nullable=False,
342        comment="Unique Guild ID of parent guild",
343    )
344    user_id: orm.Mapped[int | None] = orm.mapped_column(
345        sqlalchemy.BigInteger(),
346        nullable=True,
347        comment="Unique discord-provided user ID",
348    )
349    date_created: orm.Mapped[datetime.datetime] = orm.mapped_column(
350        sqlalchemy.DateTime(),
351        nullable=False,
352        comment="Date the ticket was created",
353        server_default=UTCnow(),
354    )
355    last_response: orm.Mapped[datetime.datetime] = orm.mapped_column(
356        sqlalchemy.DateTime(),
357        nullable=False,
358        comment="Date the ticket was last responded to",
359        server_default=UTCnow(),
360    )
361    staff_note_thread: orm.Mapped[int | None] = orm.mapped_column(
362        sqlalchemy.BigInteger(),
363        nullable=True,
364        comment="Unique discord-provided channel ID of the staff note thread",
365        unique=True,
366    )
367    anonymous: orm.Mapped[bool] = orm.mapped_column(default=False,
368                                                    nullable=False,
369                                                    comment="Whether the ticket is in anonymous mode")
370    notified: orm.Mapped[bool] = orm.mapped_column(default=False,
371                                                   nullable=False,
372                                                   comment="Whether the user has been notified about this ticket")
373
374    # Relationships
375    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="tickets", lazy="selectin")
376
377    # SNOWFLAKE PROTOCOL
378    @orm.reconstructor
379    def init_on_load(self):
380        """Initiate snowflake protocol
381
382        This is a snowflake protocol, which is a way to make the channel ID
383        more accessible. To use with discord.py.
384        """
385        self.id = self.channel_id

Ticket channels table

This is the table for the ticket channels. It contains the channel ID of the ticket channel. It also contains the relationship to the Guild table. And the foreign key to the guild ID. Any closed tickets are deleted from this table.

Attributes:
  • channel_id: The unique discord-provided channel ID.
  • guild_id: The unique discord-provided guild ID.
  • user_id: The unique discord-provided user ID.
  • date_created: The date the ticket was created.
  • last_response: The date of the last response in the ticket.
  • staff_note_thread: The unique discord-provided ID of the note thread.
  • anonymous: Whether the ticket is in anonymous mode.
  • guild: The relationship to the Guild table.
Ticket(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

channel_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
user_id: sqlalchemy.orm.base.Mapped[int | None]
date_created: sqlalchemy.orm.base.Mapped[datetime.datetime]
last_response: sqlalchemy.orm.base.Mapped[datetime.datetime]
staff_note_thread: sqlalchemy.orm.base.Mapped[int | None]
anonymous: sqlalchemy.orm.base.Mapped[bool]
notified: sqlalchemy.orm.base.Mapped[bool]
guild: sqlalchemy.orm.base.Mapped[Guild]
@orm.reconstructor
def init_on_load(self):
378    @orm.reconstructor
379    def init_on_load(self):
380        """Initiate snowflake protocol
381
382        This is a snowflake protocol, which is a way to make the channel ID
383        more accessible. To use with discord.py.
384        """
385        self.id = self.channel_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the channel ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry
class Tag(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
388class Tag(Base):
389    """Tags table.
390
391    Stores the tags for the guild.
392    Tags are used to quickly respond to common questions.
393    Tags are stored in the database, so they can be
394    updated without restarting the bot.
395    Additionally, if additional columns besides "tag" and "content" are added,
396    the tag is automatically interpreted as an embed.
397
398    Attributes:
399        guild_id: The unique discord-provided guild ID.
400        tag_name: The 'key' of the tag.
401        title: The title of the embed.
402        description: The description of the embed.
403        url: The url of the embed.
404        color: The color of the embed.
405        footer: The footer of the embed.
406        image: The image of the embed.
407        thumbnail: The thumbnail of the embed.
408        author: The author of the embed.
409        guild: The relationship to the Guild table.
410    """
411
412    __tablename__ = "tags"
413    __table_args__ = {"comment": "Tags for the guilds."}
414
415    # Simple columns
416    guild_id: orm.Mapped[int] = orm.mapped_column(sqlalchemy.BigInteger(),
417                                                  sqlalchemy.ForeignKey("general_configs.guild_id"),
418                                                  nullable=False,
419                                                  comment="Unique Guild ID of parent guild",
420                                                  primary_key=True)
421    tag_name: orm.Mapped[str] = orm.mapped_column(sqlalchemy.String(32),
422                                                  nullable=False,
423                                                  comment="The 'key' of the tag",
424                                                  primary_key=True)
425    title: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
426                                                      nullable=True,
427                                                      comment="The title of the embed")
428    description: orm.Mapped[str] = orm.mapped_column(sqlalchemy.String(4096),
429                                                     nullable=False,
430                                                     comment="The description of the embed")
431    url: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
432                                                    nullable=True,
433                                                    comment="The url of the embed")
434    color: orm.Mapped[int | None] = orm.mapped_column(sqlalchemy.Integer(),
435                                                      nullable=True,
436                                                      comment="The color of the embed")
437    footer: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(2048),
438                                                       nullable=True,
439                                                       comment="The footer of the embed")
440    image: orm.Mapped[str] = orm.mapped_column(sqlalchemy.String(256), nullable=True, comment="The image of the embed")
441    thumbnail: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
442                                                          nullable=True,
443                                                          comment="The thumbnail of the embed")
444    author: orm.Mapped[str | None] = orm.mapped_column(sqlalchemy.String(256),
445                                                       nullable=True,
446                                                       comment="The author of the embed")
447
448    # Relationships
449    guild: orm.Mapped["Guild"] = orm.relationship(
450        back_populates="tags",
451        lazy="selectin",
452    )

Tags table.

Stores the tags for the guild. Tags are used to quickly respond to common questions. Tags are stored in the database, so they can be updated without restarting the bot. Additionally, if additional columns besides "tag" and "content" are added, the tag is automatically interpreted as an embed.

Attributes:
  • guild_id: The unique discord-provided guild ID.
  • tag_name: The 'key' of the tag.
  • title: The title of the embed.
  • description: The description of the embed.
  • url: The url of the embed.
  • color: The color of the embed.
  • footer: The footer of the embed.
  • image: The image of the embed.
  • thumbnail: The thumbnail of the embed.
  • author: The author of the embed.
  • guild: The relationship to the Guild table.
Tag(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

guild_id: sqlalchemy.orm.base.Mapped[int]
tag_name: sqlalchemy.orm.base.Mapped[str]
title: sqlalchemy.orm.base.Mapped[str | None]
description: sqlalchemy.orm.base.Mapped[str]
url: sqlalchemy.orm.base.Mapped[str | None]
color: sqlalchemy.orm.base.Mapped[int | None]
footer: sqlalchemy.orm.base.Mapped[str | None]
image: sqlalchemy.orm.base.Mapped[str]
thumbnail: sqlalchemy.orm.base.Mapped[str | None]
author: sqlalchemy.orm.base.Mapped[str | None]
guild: sqlalchemy.orm.base.Mapped[Guild]
Inherited Members
Base
metadata
registry
class StaffRole(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
455class StaffRole(Base):
456    """Staff roles table
457
458    This is the table for the staff roles.
459    It contains the role ID of the staff role.
460    It also contains the relationship to the Guild table.
461    And the foreign key to the guild ID.
462
463    Attributes:
464        role_id: The unique discord-provided role ID.
465        guild_id: The unique discord-provided guild ID.
466        guild: The relationship to the Guild table.
467    """
468
469    __tablename__ = "staff_roles"
470    __table_args__ = {
471        "comment": ("Roles that are allowed to view ticket notes,"
472                    " and have access to staff commands.")
473    }
474
475    # Simple columns
476    role_id: orm.Mapped[int] = orm.mapped_column(
477        sqlalchemy.BigInteger(),
478        primary_key=True,
479        comment=("Unique discord-provided role ID,"
480                 " this is the primary key as it is unique across guilds"),
481    )
482    guild_id: orm.Mapped[int] = orm.mapped_column(
483        sqlalchemy.BigInteger(),
484        sqlalchemy.ForeignKey("general_configs.guild_id"),
485        nullable=False,
486        comment="Unique Guild ID of parent guild",
487    )
488
489    # Relationships
490    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="staff_roles", lazy="selectin")
491
492    # SNOWFLAKE PROTOCOL
493    @orm.reconstructor
494    def init_on_load(self):
495        """Initiate snowflake protocol
496
497        This is a snowflake protocol, which is a way to make the role ID
498        more accessible. To use with discord.py.
499        """
500        self.id = self.role_id

Staff roles table

This is the table for the staff roles. It contains the role ID of the staff role. It also contains the relationship to the Guild table. And the foreign key to the guild ID.

Attributes:
  • role_id: The unique discord-provided role ID.
  • guild_id: The unique discord-provided guild ID.
  • guild: The relationship to the Guild table.
StaffRole(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

role_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
guild: sqlalchemy.orm.base.Mapped[Guild]
@orm.reconstructor
def init_on_load(self):
493    @orm.reconstructor
494    def init_on_load(self):
495        """Initiate snowflake protocol
496
497        This is a snowflake protocol, which is a way to make the role ID
498        more accessible. To use with discord.py.
499        """
500        self.id = self.role_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the role ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry
class ObserversRole(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
503class ObserversRole(Base):
504    """Observer roles table
505
506    This is the table for the observer roles.
507    It contains the role ID of the observer role.
508    It also contains the relationship to the Guild table.
509    And the foreign key to the guild ID.
510
511    Attributes:
512        role_id: The unique discord-provided role ID.
513        guild_id: The unique discord-provided guild ID.
514        guild: The relationship to the Guild table.
515    """
516
517    __tablename__ = "observer_roles"
518    __table_args__ = {"comment": "Roles that are automatically added to tickets notes."}
519
520    # Simple columns
521    role_id: orm.Mapped[int] = orm.mapped_column(
522        sqlalchemy.BigInteger(),
523        primary_key=True,
524        comment=("Unique discord-provided role ID,"
525                 " this is the primary key as it is unique across guilds"),
526    )
527    guild_id: orm.Mapped[int] = orm.mapped_column(
528        sqlalchemy.BigInteger(),
529        sqlalchemy.ForeignKey("general_configs.guild_id"),
530        nullable=False,
531        comment="Unique Guild ID of parent guild",
532    )
533
534    # Relationships
535    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="observers_roles", lazy="selectin")
536
537    # SNOWFLAKE PROTOCOL
538    @orm.reconstructor
539    def init_on_load(self):
540        """Initiate snowflake protocol
541
542        This is a snowflake protocol, which is a way to make the role ID
543        more accessible. To use with discord.py.
544        """
545        self.id = self.role_id

Observer roles table

This is the table for the observer roles. It contains the role ID of the observer role. It also contains the relationship to the Guild table. And the foreign key to the guild ID.

Attributes:
  • role_id: The unique discord-provided role ID.
  • guild_id: The unique discord-provided guild ID.
  • guild: The relationship to the Guild table.
ObserversRole(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

role_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
guild: sqlalchemy.orm.base.Mapped[Guild]
@orm.reconstructor
def init_on_load(self):
538    @orm.reconstructor
539    def init_on_load(self):
540        """Initiate snowflake protocol
541
542        This is a snowflake protocol, which is a way to make the role ID
543        more accessible. To use with discord.py.
544        """
545        self.id = self.role_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the role ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry
class CommunityRole(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
548class CommunityRole(Base):
549    """Community roles table
550
551    This is the table for the community roles.
552    It contains the role ID of the community role.
553    It also contains the relationship to the Guild table.
554    And the foreign key to the guild ID.
555
556    Attributes:
557        role_id: The unique discord-provided role ID.
558        guild_id: The unique discord-provided guild ID.
559        guild: The relationship to the Guild table.
560    """
561
562    __tablename__ = "community_roles"
563    __table_args__ = {"comment": "Roles that are allowed to view tickets, but aren't staff."}
564
565    # Simple columns
566    role_id: orm.Mapped[int] = orm.mapped_column(
567        sqlalchemy.BigInteger(),
568        primary_key=True,
569        comment=("Unique discord-provided role ID,"
570                 " this is the primary key as it is unique across guilds"),
571    )
572    guild_id: orm.Mapped[int] = orm.mapped_column(
573        sqlalchemy.BigInteger(),
574        sqlalchemy.ForeignKey("general_configs.guild_id"),
575        nullable=False,
576        comment="Unique Guild ID of parent guild",
577    )
578
579    # Relationships
580    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="community_roles", lazy="selectin")
581
582    # SNOWFLAKE PROTOCOL
583    @orm.reconstructor
584    def init_on_load(self):
585        """Initiate snowflake protocol
586
587        This is a snowflake protocol, which is a way to make the role ID
588        more accessible. To use with discord.py.
589        """
590        self.id = self.role_id

Community roles table

This is the table for the community roles. It contains the role ID of the community role. It also contains the relationship to the Guild table. And the foreign key to the guild ID.

Attributes:
  • role_id: The unique discord-provided role ID.
  • guild_id: The unique discord-provided guild ID.
  • guild: The relationship to the Guild table.
CommunityRole(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

role_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
guild: sqlalchemy.orm.base.Mapped[Guild]
@orm.reconstructor
def init_on_load(self):
583    @orm.reconstructor
584    def init_on_load(self):
585        """Initiate snowflake protocol
586
587        This is a snowflake protocol, which is a way to make the role ID
588        more accessible. To use with discord.py.
589        """
590        self.id = self.role_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the role ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry
class CommunityPing(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
593class CommunityPing(Base):
594    """Community pings table
595
596    This is the table for the community pings.
597    It contains the role ID of the community ping role.
598    It also contains the relationship to the Guild table.
599    And the foreign key to the guild ID.
600
601    Attributes:
602        role_id: The unique discord-provided role ID.
603        guild_id: The unique discord-provided guild ID.
604        guild: The relationship to the Guild table.
605    """
606
607    __tablename__ = "community_pings"
608    __table_args__ = {
609        "comment": ("Table for community pings,"
610                    " pinged when a ticket is opened but"
611                    " after adding the community roles.")
612    }
613
614    # Simple columns
615    role_id: orm.Mapped[int] = orm.mapped_column(
616        sqlalchemy.BigInteger(),
617        primary_key=True,
618        comment=("Unique discord-provided role ID,"
619                 " this is the primary key as it is unique across guilds"),
620    )
621    guild_id: orm.Mapped[int] = orm.mapped_column(
622        sqlalchemy.BigInteger(),
623        sqlalchemy.ForeignKey("general_configs.guild_id"),
624        nullable=False,
625        comment="Unique Guild ID of parent guild",
626    )
627
628    # Relationships
629    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="community_pings", lazy="selectin")
630
631    # SNOWFLAKE PROTOCOL
632    @orm.reconstructor
633    def init_on_load(self):
634        """Initiate snowflake protocol
635
636        This is a snowflake protocol, which is a way to make the role ID
637        more accessible. To use with discord.py.
638        """
639        self.id = self.role_id

Community pings table

This is the table for the community pings. It contains the role ID of the community ping role. It also contains the relationship to the Guild table. And the foreign key to the guild ID.

Attributes:
  • role_id: The unique discord-provided role ID.
  • guild_id: The unique discord-provided guild ID.
  • guild: The relationship to the Guild table.
CommunityPing(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

role_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
guild: sqlalchemy.orm.base.Mapped[Guild]
@orm.reconstructor
def init_on_load(self):
632    @orm.reconstructor
633    def init_on_load(self):
634        """Initiate snowflake protocol
635
636        This is a snowflake protocol, which is a way to make the role ID
637        more accessible. To use with discord.py.
638        """
639        self.id = self.role_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the role ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry
class Member(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
642class Member(Base):
643    """Member table
644
645    This is the table for the members.
646    It is an association table between the users and the guilds.
647    It contains the user ID and the guild ID.
648    It also contains a relationship to both the User and Guild tables.
649    It will also contain any bot information about the user.
650
651    Attributes:
652        user_id: The unique discord-provided user ID.
653        guild_id: The unique discord-provided guild ID.
654        user: The relationship to the User table.
655        guild: The relationship to the Guild table.
656    """
657
658    __tablename__ = "members"
659    __table_args__ = {
660        "comment": ("Table for members,"
661                    " this is a combination of a user and a guild,"
662                    " as a user can be in multiple guilds.")
663    }
664
665    # Simple columns
666    user_id: orm.Mapped[int] = orm.mapped_column(
667        sqlalchemy.BigInteger(),
668        sqlalchemy.ForeignKey("users.user_id"),
669        nullable=False,
670        comment=("Unique discord-provided user ID."
671                 " Used in conjunction with guild_id to make a unique primary key"),
672        primary_key=True,
673        unique=False,
674    )
675    guild_id: orm.Mapped[int] = orm.mapped_column(
676        sqlalchemy.BigInteger(),
677        sqlalchemy.ForeignKey("general_configs.guild_id"),
678        nullable=False,
679        comment=("Unique Guild ID of parent guild."
680                 " Used in conjunction with user_id to make a unique primary key"),
681        primary_key=True,
682        unique=False,
683    )
684    status: orm.Mapped[int] = orm.mapped_column(
685        sqlalchemy.Integer(),
686        nullable=False,
687        default=0,
688        comment=("The status of the member, 0 is normal, "
689                 "1 is support-blocked, 2 is barred from providing support"),
690    )
691    status_till: orm.Mapped[datetime.datetime | None] = orm.mapped_column(
692        sqlalchemy.DateTime(),
693        nullable=True,
694        comment=("The time until the status is removed, "
695                 "if None, the status is permanent"),
696        default=None)
697
698    # Relationships
699    guild: orm.Mapped["Guild"] = orm.relationship(back_populates="members", lazy="selectin")
700    user: orm.Mapped["User"] = orm.relationship(back_populates="memberships", lazy="selectin")

Member table

This is the table for the members. It is an association table between the users and the guilds. It contains the user ID and the guild ID. It also contains a relationship to both the User and Guild tables. It will also contain any bot information about the user.

Attributes:
  • user_id: The unique discord-provided user ID.
  • guild_id: The unique discord-provided guild ID.
  • user: The relationship to the User table.
  • guild: The relationship to the Guild table.
Member(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

user_id: sqlalchemy.orm.base.Mapped[int]
guild_id: sqlalchemy.orm.base.Mapped[int]
status: sqlalchemy.orm.base.Mapped[int]
status_till: sqlalchemy.orm.base.Mapped[datetime.datetime | None]
guild: sqlalchemy.orm.base.Mapped[Guild]
user: sqlalchemy.orm.base.Mapped[User]
Inherited Members
Base
metadata
registry
class User(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
703class User(Base):
704    """User table
705
706    This is the table for the users.
707    It contains the user ID.
708    It also contains a relationship to the Member table.
709    It will also contain any bot information about the user.
710
711    Attributes:
712        user_id: The unique discord-provided user ID.
713        memberships: The relationship to the Member table.
714        is_owner: Is the user the owner of the bot?
715    """
716
717    __tablename__ = "users"
718    __table_args__ = {
719        "comment": ("Table for users,"
720                    " this is not a guild-specific table,"
721                    " as a user can be in multiple guilds.")
722    }
723
724    # Simple columns
725    user_id: orm.Mapped[int] = orm.mapped_column(
726        sqlalchemy.BigInteger(),
727        primary_key=True,
728        comment=("Unique discord-provided user ID,"
729                 " this is the primary key as it is unique across guilds"),
730    )
731
732    # Toggles
733    is_owner: orm.Mapped[bool] = orm.mapped_column(default=False, comment="Is the user the owner of the bot?")
734
735    # Relationships
736    memberships: orm.Mapped[list["Member"]] = orm.relationship(back_populates="user", lazy="raise")
737    # Disabled for now gets sqlalchemy confused
738    # pylint: disable=line-too-long
739    # guilds: orm.Mapped[list["Guild"]] = orm.relationship(
740    #    secondary="members", back_populates="users", lazy="raise", viewonly=True
741    # )
742
743    # SNOWFLAKE PROTOCOL
744    @orm.reconstructor
745    def init_on_load(self):
746        """Initiate snowflake protocol
747
748        This is a snowflake protocol, which is a way to make the user ID
749        more accessible. To use with discord.py.
750        """
751        self.id = self.user_id

User table

This is the table for the users. It contains the user ID. It also contains a relationship to the Member table. It will also contain any bot information about the user.

Attributes:
  • user_id: The unique discord-provided user ID.
  • memberships: The relationship to the Member table.
  • is_owner: Is the user the owner of the bot?
User(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

user_id: sqlalchemy.orm.base.Mapped[int]
is_owner: sqlalchemy.orm.base.Mapped[bool]
memberships: sqlalchemy.orm.base.Mapped[list[Member]]
@orm.reconstructor
def init_on_load(self):
744    @orm.reconstructor
745    def init_on_load(self):
746        """Initiate snowflake protocol
747
748        This is a snowflake protocol, which is a way to make the user ID
749        more accessible. To use with discord.py.
750        """
751        self.id = self.user_id

Initiate snowflake protocol

This is a snowflake protocol, which is a way to make the user ID more accessible. To use with discord.py.

Inherited Members
Base
metadata
registry