Database
Helpers
- flashcards_core.database.init_db(database_path: str = 'sqlite:////home/runner/work/flashcards-core/flashcards-core/docs/sqlite_dev.db', connect_args: Mapping[str, Any] = {'check_same_thread': False})
Initializes the database connection. Creates an SQLAlchemy engine, makes sure all tables exist, and returns a sessionmaker that can be used to generate a database connection.
Note: the default connect_args is needed only for SQLite.
- Parameters
database_path – The database URL. Can be used to specify the database type with the protocol (‘sqlite:///’, ‘postgres:///’, …)
connect_args – other arguments to pass to the SQLAlchemy engine. See SQLAlchemy documentation for sqlalchemy.create_engine()
- Returns
a sessionmaker, a function that can be called to return a Session object.
Example usage:
from sqlalchemy.orm import Session from flashcards_core.database import init_db # Initialize the database connection sessionmaker = init_db() session: Session = sessionmaker() fact = Fact.create(session=session, value="A fact", format="text")
CRUD Base class
- class flashcards_core.database.crud.CrudOperations
Bases:
object
- classmethod create(session: sqlalchemy.orm.session.Session, **kwargs)
Create a new model object with the given kwargs. Check the model to understand what you can give as **kwargs.
- Parameters
session – the session (see flashcards_core.database:init_session()).
- Returns
the new model object.
- async classmethod create_async(session: sqlalchemy.orm.session.Session, **kwargs)
Create a new model object with the given kwargs. Check the model to understand what you can give as **kwargs (asyncio-friendly).
- Parameters
session – the session (see flashcards_core.database:init_session()).
- Returns
the new model object.
- classmethod delete(session: sqlalchemy.orm.session.Session, object_id: int) None
Delete a model object.
- Parameters
session – the session (see flashcards_core.database:init_session()).
object_id – the ID of the model object to delete.
- Returns
None.
- Raises
ObjectNotFoundException if no object with the given ID was found in the database.
- async classmethod delete_async(session: sqlalchemy.orm.session.Session, object_id: int) None
Delete a model object (asyncio-friendly).
- Parameters
session – the session (see flashcards_core.database:init_session()).
object_id – the ID of the model object to delete.
- Returns
None.
- Raises
ObjectNotFoundException if no object with the given ID was found in the database.
- classmethod get_all(session: sqlalchemy.orm.session.Session, offset: int = 0, limit: int = 100) List
Returns a list of all the model objects available in the DB, or a subset of them.
- Parameters
session – the session (see flashcards_core.database:init_session()).
offset – for pagination, index at which to start returning values.
limit – for pagination, maximum number of elements to return.
- Returns
List of model objects.
- async classmethod get_all_async(session: sqlalchemy.orm.session.Session, offset: int = 0, limit: int = 100) List[Any]
Returns a list of all the model objects available in the DB, or a subset of them (asyncio-friendly).
- Parameters
session – the session (see flashcards_core.database:init_session()).
offset – for pagination, index at which to start returning values.
limit – for pagination, maximum number of elements to return.
- Returns
List of model objects.
- classmethod get_one(session: sqlalchemy.orm.session.Session, object_id: int) Optional
Returns the model object corresponding to the given ID.
- Parameters
session – the session (see flashcards_core.database:init_session()).
object_id – the ID of the model object to return.
- Returns
the matching model object.
- async classmethod get_one_async(session: sqlalchemy.orm.session.Session, object_id: int) Optional[Any]
Returns the model object corresponding to the given ID (asyncio-friendly).
- Parameters
session – the session (see flashcards_core.database:init_session()).
object_id – the ID of the model object to return.
- Returns
the matching model object.
- classmethod update(session: sqlalchemy.orm.session.Session, object_id: int, **kwargs)
Modify the model object with the given values. Check the model to understand what you can give as **kwargs.
- Parameters
session – the session (see flashcards_core.database:init_session()).
object_id – the ID of the model object to update.
- Returns
the updated model object.
- Raises
ObjectNotFoundException if no model object with the given ID was found in the database.
- async classmethod update_async(session: sqlalchemy.orm.session.Session, object_id: int, **kwargs)
Modify the model object with the given values. Check the model to understand what you can give as **kwargs (asyncio-friendly).
- Parameters
session – the session (see flashcards_core.database:init_session()).
object_id – the ID of the model object to update.
- Returns
the updated model object.
- Raises
ObjectNotFoundException if no model object with the given ID was found in the database.
Export Utils
- flashcards_core.database.exporter.DEFAULT_EXCLUDE_FIELDS = {'cards': ['deck']}
Default fields not to follow for related objects discovery. See export_to_json() for more info
- flashcards_core.database.exporter.export_to_dict(session: sqlalchemy.orm.session.Session, objects_to_export: List[sqlalchemy.orm.decl_api.Base], exclude_fields: Optional[Mapping[str, List[str]]] = None, _hierarchy: Optional[Mapping[str, Any]] = None) Mapping[str, Any]
Exports the given objects to a dictionary, which can be easily dumped into a standard format like JSON or YAML.
Note that, by default, all relationships are followed, except for the following ones:
Exporting a Card won’t export its Deck.
Exporting a Fact will not export the Cards it’s included in.
These default can be overridden by providing a value to the exclude_fields attribute. It expect a mapping of a tablename (like ‘cards’) and a list of string with the name of the columns that should not be checked for potential related objects to export. Its default value looks like
{'cards': ['deck']}
(facts don’t have references to the cards they’re included in, so you need a query to find them).Remember to pass an empty dictionary to exclude_fields to really exclude no fields; passing None will instruct this function to apply the default exclusion list.
The list of objects to export can be a mixture of several subclasses of SQLAlchemy’s Base class. In the output they will be categorized by table name.
Example output where only one Deck object was passed:
{ 'decks': { 1: { 'name': 'Test Deck', 'description': 'A deck for tests', 'algorithm': 'random', 'parameters': { 'unseen_first': true }, 'state': { 'last_reviewed_card': 2 } } }, 'cards': { 1: { 'deck_id': 1, 'question_id': 1, 'answer_id': 2 } }, 'facts': { 1: { 'value': 'A question', 'format': 'text' }, 2: { 'value': 'An answer', 'format': 'text' } }, 'reviews': { 1: { 'card_id': 1, 'result': True, 'algorithm': 'random', 'datetime': '2021-01-01 12:00:00' } }, 'tags': { 1: { 'name': 'test-tag-1' }, 2: { 'name': 'test-tag-2' } } 'decktags': { (1, 1), (1, 2) } }
If more Decks were passed, the overall structure would be the same, as well as if the list was made of mixed objects.
- Parameters
session – the session (see flashcards_core.database:init_session()).
objects_to_export – a list of objects to export. They should be subclasses of any class defined in flashcards_core.database.models.
exclude_fields – If any of the model object columns should not be followed, they should be added here. Note that these exclusions apply to all the objects of this type discovered by following other relationships. The default value is set to
{'cards': ['deck']}
(see above)._hierarchy – internal, used to pass the already built hierarchy through recursive calls.
- Returns
a definition of all the objects required to reconstruct the database hierarchy the objects were taken from.
- flashcards_core.database.exporter.export_to_json(session: sqlalchemy.orm.session.Session, objects_to_export: List[sqlalchemy.orm.decl_api.Base], exclude_fields: Optional[Mapping[str, List[str]]] = None, **json_kwargs) str
Exports the given objects into a JSON string. Simple wrapper around export_to_dict() that performs some normalization (like UUIDs to string, set to list, etc…)
- Parameters
session – the session (see flashcards_core.database:init_session()).
objects_to_export – a list of objects to export. They should be subclasses of any class defined in flashcards_core.database.models.
json_kwargs – any parameter you may wish to pass to json.dumps()
- flashcards_core.database.exporter.hierarchy_to_json(obj)
JSON serializer for objects not serializable by default, like dates, sets, UUIDs.
This is the ‘default’ method of the JSON encoder, see export_to_json.
Import Utils
- flashcards_core.database.importer.datetime_hook(json_dict)
- flashcards_core.database.importer.import_from_dict(session: sqlalchemy.orm.session.Session, hierarchy: Mapping[str, Any], stop_on_error=False) None
Create objects in the database from the data contained in the dictionary. Note that the keys must be strings, not UUID objects.
Example of valid input:
{ 'decks': { 1: { 'name': 'Test Deck', 'description': 'A deck for tests', 'algorithm': 'random', 'parameters': { 'unseen_first': true }, 'state': { 'last_reviewed_card': 2 } } }, 'cards': { 1: { 'deck_id': 1, 'question_id': 1, 'answer_id': 2 } }, 'facts': { 1: { 'value': 'A question', 'format': 'text' }, 2: { 'value': 'An answer', 'format': 'text' } }, 'reviews': { 1: { 'card_id': 1, 'result': True, 'algorithm': 'random', 'datetime': '2021-01-01 12:00:00' } }, 'tags': { 1: { 'name': 'test-tag-1' }, 2: { 'name': 'test-tag-2' } } 'decktags': { (1, 1), (1, 2) } }
- Parameters
session – the session (see flashcards_core.database:init_session()).
hierarchy – a dictionary containing all the data of the objects to import. See above or export_to_dict() for more info.
stop_on_error – if an Integrity error is raised, stop instead of skipping the object.
- Returns
None
- flashcards_core.database.importer.import_from_json(session: sqlalchemy.orm.session.Session, json_string: str, stop_on_error=False, **json_kwargs) None
Import the objects from their JSON representation. Simple wrapper around import_from_dict().
- Parameters
session – the session (see flashcards_core.database:init_session()).
json_string – the string containing the data of the objects to import. It should have been created with export_to_json() or match the same schema.
json_kwargs – any parameter you may wish to pass to json.loads()
- flashcards_core.database.importer.import_to_associative_table(session: sqlalchemy.orm.session.Session, table: sqlalchemy.sql.schema.Table, tablename: str, entities: dict, stop_on_error: bool) None
- flashcards_core.database.importer.import_to_table(session: sqlalchemy.orm.session.Session, table: sqlalchemy.sql.schema.Table, tablename: str, entities: dict, stop_on_error: bool) None