-
-
Notifications
You must be signed in to change notification settings - Fork 402
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
db: adding multi database support #1446
Conversation
0890294
to
80cab9e
Compare
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.
Thanks for the work @RustyBower, just a few comments ;)
sopel/config/core_section.py
Outdated
@@ -96,8 +96,23 @@ class CoreSection(StaticSection): | |||
channels = ListAttribute('channels') | |||
"""List of channels for the bot to join when it connects""" | |||
|
|||
db_type = ValidatedAttribute('db_type') | |||
"""The type of database to use for Sopel's database. (SQLite or MySQL)""" |
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.
Can we simply refer to sqlalchemy docs instead of limiting choices?
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'd love for this to be a ChoiceAttribute
, for the automatic error message Sopel would spit out if configured to an unknown value, but that would certainly wind up biting us at some point when SQLAlchemy adds support for some newfangled database type that Sopel doesn't know about…
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.
That's probably going to be infrequent though and a minor PR to address, that seems like a reasonable choice. Downside to this is that it limits usability in non-standard databases. There are some that ship supported in SQLAlchemy and others that are through external packages.
The docs for what Dialects (databases) SQLAlchemy supports (as in listed on their website): https://docs.sqlalchemy.org/en/latest/dialects/index.html
After thinking about it, given that SQLAlchemy could have any database plugin written and then consumed since anyone could write a new Dialect for SQLAlchemy, it'd probably be best to not limit this by using a ChoiceAttribute. I think warning when a connection couldn't be made instead is best.
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've made this a ChoiceAttribute for now. It looks like there aren't that many dialects to deal with (7), and honestly people only probably use 4 of those (sqlite, mysql, postgres, and mssql).
The biggest question is how we are going to handle dependencies for these, since mysql requires pymysql, etc. Is that something that should be documented or should the PyMySQL dependency be included in requirements (which would also need to include the dependencies for all other database dialects, and that feels bad)
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.
Dependencies for the various dialects should be left to documentation, IMO. Adding them all to requirements would partially defeat the purpose of making the backend a choice, because the point is to use SQLite (from Python's standard library) unless the user specifically sets it up otherwise. And to do that, they should need to read some documentation. 😸
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 like it. I've added some of the basic stuff into coretasks, but I will definitely update README with some more of the different db backend requirements.
c4a576d
to
4b8ddc5
Compare
Just finished testing. MSSQL, MySQL, Postgres, and SQLite all work. I am unable to test Oracle because apparently you need to pay for a license. I haven't tested the last 2 (firebird or sybase). I don't love having String(255) everywhere, but I'm unable to just have String, since it causes MySQL to explode. I'm still looking at other options. |
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.
Gave this a preliminary once-over. Nothing major, but a few things did jump out.
(Some stuff was already fixed after @cerealcable's review, so 👍 for that!)
All addressed; need to re-review after testing for real.
e58d6f3
to
2c0b884
Compare
2c0b884
to
fa5bb2b
Compare
@RustyBower I think you messed up this PR the other day, like you did with the reddit plugin one. Review conversations that were marked as resolved are missing their resolutions in the current PR state. Looks like 2c0b884 was the last good state. |
@RustyBower Still broken compared to before. A lot of issues that were fixed as of 2c0b884 are present again in the current state, because some commits are missing. Merging upstream into a feature branch is a bad idea. I suggest doing a |
e57aa7f
to
2c0b884
Compare
This should be all set. I just triple checked with various databases, and it all works 👍 |
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.
Damn, naming things is really hard.
@RustyBower almost done! There is this generic Exception raised that I would like to see replaced by a more-specific one. |
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.
In sopel.db
, it appears that you did not import sopel.config
.
While you are at it, could you replace from sopel.tools import Identifier
by this:
from sopel import config, tools
and then use tools.Identifier
and config.ConfigurationError
when needed?
Squashed all the commits, should be ready for the big show now |
Too bad everything's not green. There's an undefined name, that |
c2afc79
to
8c2d8bc
Compare
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 good news is, my comments fall squarely in the "nitpick" category. 😃
Bad news is, you're still not done force-pushing this PR, because at least a couple of them are actually important nitpicks. 😦
(But I suggest you address these in new commits and rebase after the PR is approved—sound good?)
e43a475
to
b922cfb
Compare
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.
This is 👍 pending me getting a chance to put it through some paces on an actual instance (though I shouldn't need to if the DB tests pass, right? 😛)
Future plans: Documentation updates to the README, and possibly adding setuptools extras for the different DB options.
Very excited for this, will bot owners have any way to migrate existing sqlite content to another database? |
Not currently, but there exist some tools like https://github.com/seanharr11/etlalchemy that can do the migrations between any of the now supported DBs |
Or ever, probably. I don't think it's Sopel's responsibility to offer migration from one database back-end to another. Existing users have numerous options from which to choose if they want to move away from SQLite, just like they had their choice of tools for moving to SQLite when Willie 5.0 came out. If it "wasn't our problem" when dropping support for other database engines, it certainly "isn't our problem" when adding (back) support for engines other than SQLite while still keeping SQLite support. |
It's still good to note that there is a solution though. |
I think this PR is ready to be merged. We should then improve the following points:
which can be all done in future PR. |
Assigning to @RustyBower as a reminder. We agreed on IRC that I'll merge this once some rudimentary documentation on the more popular drivers is in place. Basic docs (in the readme here and in a section at https://sopel.chat/usage/installing/ — a separate PR to sopel-irc/sopel.chat) should cover sqlite, mysql, and pgsql at minimum. Anything more obscure can wait, I think. Not many of us would want to buy, say, an Oracle license just to document it. 😁 |
b922cfb
to
efd345b
Compare
60a74a5
to
8a78393
Compare
8a78393
to
00ebf26
Compare
Should be all set with README configuration |
This should fix #736.
This PR migrates from direct SQLite SQL statements to using the SQLAlchemy ORM. This will allow users to choose whether they want to stick with SQLite (Default), or leverage another database engine.
I've added a few more variables to core to handle non-SQLite databases: db_type, db_user, db_pass, db_host, and db_name. If db_type is not specified, or is specified with sqlite, the other values do not need to be specified. If db_type is specified with MySQL, users will need to specify the other parameters.
We could probably move the Models into their own model.py to clean things up a bit, but I will leave that to your discretion @dgw