Chryso is an outgrowth of our work with SQLAlchemy. SQLAlchemy is excellent, but we found that we kept building similar structures on top of it and wanted some way of sharing those structures between projects. Chryso will grow organically as we need it, but for now it has three major components: * Database connection/transaction management * Error parsing * Filter-to-query translation



Update to SQLAlchemy 1.1.11


Update alembic to 0.9.2


Previously any Resource would prevent the creation of a new resource that included 'created', 'updated' or 'deleted' via the _sanitize_kwargs function on the Resouce class. That is still in place, but now descendent classes can change the fields that are excluded via the PROPERTY_CREATION_BLACKLIST property on the class


Add support for order and limit clauses


Add log message when creating or updating resources so we automatically get more traceability


Remove atomic semaphore in favor of a thread pool that is aware of threads and just creates a new connection per thread


Log a warning if a thread waits on the atomic semaphore for 30 seconds. This is useful for debugging semaphore lockout


Do not allow multiple threads to enter atomic blocks at the same time. We use a simple semaphore to prevent this. It's important because without it we get transaction state bleeding over across threads


Convert Enums when creating, updating and filtering resources automatically. Also handle filters that are not specified as an iterable but are a FilterArgument (or equivalent).


repr(Enum) is now equivalent to str(Enum). This may help with serialization. May not.


Additional logs around transaction management at the DEBUG level


Fix installation on windows when git isn't installed or in the PATH


Update to latest psycopg2 - 2.6.2. This is my attempt to get chryso installed on a windows machine...


Allow hashing of Enum so it can be used as a key in dicts


Auto push updates to PyPI


Allow users of the Resource class to override how the base query is created. Previously this was contained within a function doing other work. Now it's in a separate function so it can be easily overridden


Change the default naming convention for uniqueness constraints so that we can continue to use Column(..., unique=True). Without this change (so in the entire 1 series) we get an unhandled exception from sqlalchemy if we define a column with this option enabled. That's bad.

The new logic looks at the number of columns and generates the constraint name deterministically, but dynamically, so it can properly be backwards compatible and handle the unique=True paramter 1.10

Add support for parsing check constraint errors


Add arrow to list of dependecies. Also change apply_filter to accept FilterArgument for _filter argument. This lets us query between dates.

Depending on how your client uses the queryfilter module you may need to change the way the function is getting called. Going forward you'll need to be sure that you are passing in a dictionary with a key/value mapping of columns to lists. The list contains something like a FilterArgument and ANDs them together. Within a FilterAgrument the values property is ORd together with the given operation.


Add pycountry package to list of dependencies. It can be shared between applications to get a list of countries and currencies.


Set TimeZone to UTC for all connections.


Changed METADATA to metadata in chryso.schema.

Fixed primary key to have a posgres server default which allows the database to generate a uuid on the column default.


Add Resource platform layer base class and schema table helper


Fix memory leak by not honoring the track_query parameter to Engine()


Refactor session handling logic to separate out sessions from transactions


Reworked session support so that atomic() works on engines themselves and our db fixture returns the db engine rather than a session. This means that some interactions with the fixtures may need to change in clients of the library.

I pulled away from the SQLAlchemy Session implementation and rolled my own after a long, frustrating session trying to get the behavior I want out of SQLAlchemy with psycopg2


Initial release