-
-
Notifications
You must be signed in to change notification settings - Fork 354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tortoise.init() refactoring and transactions module #29
Conversation
Pull Request Test Coverage Report for Build 108
💛 - Coveralls |
await generate_schema(client) | ||
|
||
tournament = Tournament(name='New Tournament') | ||
await Tortoise.init(config_file='config.json') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we please have this split up?
I mean Tortoise.init()
should instead recieve configuration in a dict, and for cases where we want to have support of config files or enviromment variables should be done as a layer above that.
This will make it easier to wrap the ORM in another framework.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well - it already receives config as dict as main method of init - look for postgres example.
config_file
is just alternative option for those who use tortoise directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
'port': '54325', | ||
'user': 'tortoise', | ||
'password': 'qwerty123', | ||
'database': 'test', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to use the db_url stuff I did?
It is a lot more concise, and since we changed over to DB-URLS at work it really made configuration much simpler, as e.g. with Docker you can easily inject environment variables, so we use that for configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's possible. I refactored db_url
to config_generator
- you can see how config generated for it in test_db_url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel we should make the examples use that, as it is more concise.
Or just document both, a "shorthand" that is fine for most use cases, and an "advanced"?
saved_event = await Event.filter(name='Updated name').first() | ||
print(saved_event) | ||
|
||
@atomic() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YAY!
I had lots of reservations about how transactions worked, as they were very non-intuive.
Is it possible to do with atomic:
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do it with async with in_transaction():
without calling it from connection. I separated methods because I am not sure it's intuitive to have function overloaded with two separate effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to me to use the same word.
The decorator wraps the whole function in a transaction.
The with statement wraps the whole block in a transaction.
A different question, I wanted to do a test case where I do the following (but could not get it working with the previous transaction system):
- Enter transaction
- make change 1
- Test change 1
- Commit
- Test change 1
- make change 2
- test change 2
- rollback
- test change 2 fail
Could you add such a test case (and any variations you can think of)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good so far
tortoise/__init__.py
Outdated
) | ||
|
||
related_model._meta.backward_fk_fields.add(backward_relation_name) | ||
related_model._meta.fetch_fields.add(backward_relation_name) | ||
related_model._meta.fields_map[backward_relation_name] = fk_relation | ||
related_model._meta.fields_map[backward_relation_name] = relation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I split relation
into fk_relation
and m2m_relation
was because these two variables are actually different types, and the type checker got really badly confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it's just my bad, I merged it badly today, will revert back
|
||
|
||
def expand_db_url(db_url: str, testing: bool = False) -> dict: | ||
def generate_config( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I like this.
Please try to keep to the single responsibility principal where you can.
e.g.
One function to resolve the {engine-credentials}
dict, and another to generate the config per app.
Mostly to keep it easier to test, but also minimises function complexity, so makes it less invasive when one inevitably wants to refactor something.
tortoise/contrib/test/__init__.py
Outdated
An asyncio capable test class that will ensure that an partially isolated test db | ||
is available for each test. | ||
An asyncio capable test class that will ensure that each test will be run at | ||
separate transaction that will rollback on finish. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
tox.ini
Outdated
@@ -1,5 +1,5 @@ | |||
[tox] | |||
envlist = py{35,36}-{sqlite,postgres} | |||
envlist = py{36,37}-{sqlite,postgres} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can leave it as py{35,36,37}...
and then just set:
skip_missing_interpreters = True
To skip that which you don't have installed.
…ds (ex: char in unittest)
I have been playing with the test runner, there is a lot of things not quite right for the test runner. I have added initialiser and finaliser so that Anyways I'm just stating that I'm refactoring the test suite again. |
Feature/python3.7
If a pk isn't defined, we create a pk called id for that model. Also added Model method tests.
Default model pk: id = fields.IntField(pk=True)
I have been building tests for init, and actually now have feedback to give. |
Update 1: * Fixed resource leak in init_tests.py Update 2: * Restored bad merge for fk_relation and m2m_relation in Tortoise.init() * More typing annotations * Tortoise.init() directly supports generate_config parameters * Break up generate_config to use generate_db_url again * Fix Model.get_or_create to return actual instance, not awaitable * get_backward_fk_filters was never called * Changed generate_config to take a dict of app: [model modules] * Changed generate_config to call DB config "default" by default. Update 3: * Fix inconsistency in shorthand format
Added more Tortoise.init() tests
@Zeliboba5 At this stage I'm happy with this PR, and I'm giving the 👍 to merge it to master. |
And great working with you 🙇♂️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@grigi Do you think we should do anything special about this PR, considering it will be backward incompatible? I don't want to publish it as 1.0 already, so may be we should just make some special mark in changelog? |
@Zeliboba5: v0.10.0 + a mention that it has breaking changes re init should be enough, I think. |
…ise-orm into feature/mysql
MySQL support
#14
This seems to be biggest change that occurred to tortoise and first one to bring so much backward incompatible changes.
Tortoise.init()
is now coroutine that handles all connections and models discovery.This is still work in progress, I want to make few more changes, update all documentation and may be some more tests.