Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Type mysql dialect #12164

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

Closed
wants to merge 3 commits into from
Closed

Type mysql dialect #12164

wants to merge 3 commits into from

Conversation

Polandia94
Copy link
Contributor

@Polandia94 Polandia94 commented Dec 7, 2024

Tipyng of mysql dialect.

possible breaking changes:

  • on visit_sequence, visit_true and visit_false I changed the param names to be the same tht in the super class.
  • Removed tostring on array. tostring is deprecated since Python 3.2 and removed in Python3.9 so i guess we can remove that option altogheter.
  • create_connect_args on aiomysql, added an unused param _translate_args, only to have same signature as super class.
  • delete _check_unicode_returns method. on MySQLDialect_mysqldb. I think is not used after https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/1946, and is calling to a super that I think doesnt exist anymore.
  • delete _set_isolation_level, is unused, and has a super that doesnt exists anymore:
    af1b916
  • Separate _bitmap in enumerated to _bitmap and _inversed_bitmap to have type safety
  • Add inheritance from log.Identified to MySQLTableDefinitionParser, because has the decorathor @log.class_logger

Related to issue :
#6810

Copy link
Member

@CaselIT CaselIT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to ask if you have any question

@CaselIT CaselIT marked this pull request as ready for review December 10, 2024 18:41
@CaselIT
Copy link
Member

CaselIT commented Dec 10, 2024

Sorry, wanted to make the ci run but somehow made the PR no longer draft. Feel free to set again as draft

@Polandia94 Polandia94 marked this pull request as draft December 10, 2024 21:22
rowcount = cursor.executemany(statement, parameters)
if context is not None:
context._rowcount = rowcount

def _check_unicode_returns(self, connection):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uh. no one was calling this? I guess it was a leftover of when it was removed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @zzzeek

@CaselIT
Copy link
Member

CaselIT commented Dec 14, 2024

thanks for the effort! Just so you know if you want a maintainer to take over just say so :)

@CaselIT
Copy link
Member

CaselIT commented Dec 16, 2024

@Polandia94 this is starting to become a bit too big. Can you split it by any change? At the moment a logic split could be everything not in dialect/mysql followed by what's in dialect/mysql.

note that's fine also if you want to keep doing everything here then split it in multiple pr later.

@@ -40,7 +40,7 @@ async def close(self) -> None: ...

async def commit(self) -> None: ...

def cursor(self) -> AsyncIODBAPICursor: ...
def cursor(self, *args, **kwargs) -> AsyncIODBAPICursor: ...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about adding an annotation?
*args: Any, **kwargs: Any

@Polandia94
Copy link
Contributor Author

@Polandia94 this is starting to become a bit too big. Can you split it by any change? At the moment a logic split could be everything not in dialect/mysql followed by what's in dialect/mysql.

note that's fine also if you want to keep doing everything here then split it in multiple pr later.

I expect to end this work in arround 2 or 3 weeks, and after that I will divide this in a couple of PRs. Probablly 1 for not in dialect, and 2 or 3 for the dialect, so we can review better.

@zzzeek
Copy link
Member

zzzeek commented Dec 19, 2024

looks pretty substantial. i didnt see any red flags yet...

@CaselIT
Copy link
Member

CaselIT commented Dec 19, 2024

@Polandia94 this is starting to become a bit too big. Can you split it by any change? At the moment a logic split could be everything not in dialect/mysql followed by what's in dialect/mysql.
note that's fine also if you want to keep doing everything here then split it in multiple pr later.

I expect to end this work in arround 2 or 3 weeks, and after that I will divide this in a couple of PRs. Probablly 1 for not in dialect, and 2 or 3 for the dialect, so we can review better.

Looks like a plan! Ping us when you want to proceed!

@Polandia94
Copy link
Contributor Author

This is ready, so i will start to creating shorter PRs, with parts of this.
I added # type: ignore on some imports and ignore the zimports pre-commit that delete that comments.
Also create a zimports PR about that, sqlalchemyorg/zimports#43

@CaselIT
Copy link
Member

CaselIT commented Jan 7, 2025

I added # type: ignore on some imports

you can ignore untyped module erros using a module level mypy comment

also note that we try to use specific type ignores using for example # type: ignore[import-untyped] instead of a general # type: ignore

@Dreamsorcerer
Copy link
Contributor

you can ignore untyped module erros using a module level mypy comment

I'd note you can do this is the mypy.ini config, as we do (which gives us a central place to check for modules that still need to be typed):
https://github.com/aio-libs/aiohttp/blob/c738a83d5ad0c270df94b8f93a206f0c348896e5/.mypy.ini#L36-L37

also note that we try to use specific type ignores using for example # type: ignore[import-untyped] instead of a general # type: ignore

This can also be enforced with enable_error_code = ignore-without-code.

@CaselIT
Copy link
Member

CaselIT commented Feb 27, 2025

This can also be enforced with enable_error_code = ignore-without-code.

seems useful, but a current run says

Found 341 errors in 64 files (checked 248 source files)

so at the very least it will not be in this PR

sqlalchemy-bot pushed a commit that referenced this pull request Mar 17, 2025
Type of certain methods that are called by dialect, so typing dialects is easier.

Related to #12164

breaking changes:

- Change modifiers from TextClause to InmutableDict, from Mapping, as is in the other classes

Closes: #12231
Pull-request: #12231
Pull-request-sha: 514fe47

Change-Id: I29314045b2c7eb5428f8d6fec8911c4b6d5ae73e
(cherry picked from commit 4418ef79104a0e4591ff8268d75f1deb59bfcec3)
sqlalchemy-bot pushed a commit that referenced this pull request Mar 17, 2025
Type of certain methods that are called by dialect, so typing dialects is easier.

Related to #12164

breaking changes:

- Change modifiers from TextClause to InmutableDict, from Mapping, as is in the other classes

Closes: #12231
Pull-request: #12231
Pull-request-sha: 514fe47

Change-Id: I29314045b2c7eb5428f8d6fec8911c4b6d5ae73e
@Polandia94 Polandia94 marked this pull request as ready for review March 23, 2025 21:43
@Polandia94
Copy link
Contributor Author

@CaselIT I think this i ready for review.
I was waiting to #12231

Copy link
Contributor

@dlax dlax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some suggestions inline; I have skipped reviewing lib/sqlalchemy/dialects/mysql/types.py changes (lack of time for now).



@log.class_logger
class MySQLTableDefinitionParser:
class MySQLTableDefinitionParser(log.Identified):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be useful to explain in commit message (PR description) why the inheritance got changed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a typing PR, any change that's not insignificant should be taken out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed, added # type: ignore[type-var]
@log.class_logger should receive an identified, there a couple that dont receive that, shouldnt be important

@CaselIT
Copy link
Member

CaselIT commented Mar 24, 2025

@CaselIT I think this i ready for review. I was waiting to #12231

sorry but this is already an huge change, don't change also the implemented code. Things like adding additional base classes to the dialect or similar are out of scope for this PR.

These parts should be removed and if you are interested another PR can be opened for them.

Thanks

@Polandia94
Copy link
Contributor Author

@CaselIT I think this i ready for review. I was waiting to #12231

sorry but this is already an huge change, don't change also the implemented code. Things like adding additional base classes to the dialect or similar are out of scope for this PR.

These parts should be removed and if you are interested another PR can be opened for them.

Thanks

Sorry, I think i removed all changes to implemented code.

@CaselIT
Copy link
Member

CaselIT commented Mar 31, 2025

Sorry, I think i removed all changes to implemented code.

ok thanks!

@CaselIT CaselIT requested a review from sqla-tester March 31, 2025 18:19
Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision 2987941 of this pull request into gerrit so we can run tests and reviews and stuff

@sqla-tester
Copy link
Collaborator

New Gerrit review created for change 2987941: https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

sorry for the delay. looks mostly ok

not yet finished locking all files

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

pyproject.toml Outdated
@@ -46,7 +46,8 @@ Discussions = "https://github.com/sqlalchemy/sqlalchemy/discussions"
asyncio = ["greenlet>=1"]
mypy = [
"mypy >= 1.7",
"types-greenlet >= 2"
"types-greenlet >= 2",
"types-PyMySQL >=1.1"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

this does not seem complete judging by tox

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added
types-mysqlclient
the no tipyng are in the other dependencies(also added cymysql that was nowhere).

tox.ini Outdated
mysql-connector-python
cymysql
asyncmy
aiomysql
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

it's unfortunate that we have install so many additional types here

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @zzzeek

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

We preferred solving this by using ignores in mypy, since otherwise for each dialect we would need to install a stub and that becomes a mess very fast

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

should looked at everything now. I've noted just a few minor things

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@@ -3547,7 +3900,7 @@ class _DecodingRow:
# sets.Set(['value']) (seriously) but thankfully that doesn't
# seem to come up in DDL queries.

_encoding_compat = {
_encoding_compat: dict[Optional[str], str] = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

why optional for the key?

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is used below on
`self._encoding_compat.get(charset, charset)
and charset could be None.

would add a comment, but we can also use dict[str,str] and add a type ignore below

python/typeshed#6597

@Polandia94
Copy link
Contributor Author

@CaselIT I think i changed all comments hopefully. Not sure why are not running the checks, i guess this commits has to be ported to gerrit somehow?
Tomorrow will check again the comments and mark as solved all the solved

@CaselIT CaselIT requested a review from sqla-tester April 21, 2025 16:39
Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision b877cca of this pull request into gerrit so we can run tests and reviews and stuff

@sqla-tester
Copy link
Collaborator

Patchset b877cca added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

thanks looks mostly fine. I'll do a final pass

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

  • lib/sqlalchemy/connectors/aioodbc.py (line 143): Done
  • lib/sqlalchemy/sql/ddl.py (line 35): Done
  • lib/sqlalchemy/sql/ddl.py (line 718): Done
  • lib/sqlalchemy/sql/sqltypes.py (line 1497): Done
  • lib/sqlalchemy/sql/sqltypes.py (line 3521): Done

@@ -39,7 +40,7 @@ def _auto_fn(name: str) -> Optional[Callable[[], Type[Dialect]]]:
# hardcoded. if mysql / mariadb etc were third party dialects
# they would just publish all the entrypoints, which would actually
# look much nicer.
module = __import__(
module: Any = __import__(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

dbapi_connection.terminate()

def create_connect_args(self, url):
# _translate_args should not be defined here, is only for super class.
def create_connect_args(self, url: URL) -> ConnectArgsType: # type: ignore[override] # noqa: E501
return super().create_connect_args(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

dbapi_connection.terminate()

def create_connect_args(self, url):
# _translate_args should not be defined here, is only for super class.
def create_connect_args(self, url: URL) -> ConnectArgsType: # type: ignore[override] # noqa: E501
return super().create_connect_args(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

):
return obj._with_binary_element_type(column.type)
return element._with_binary_element_type(column.type)
elif (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@@ -3547,7 +3899,9 @@ class _DecodingRow:
# sets.Set(['value']) (seriously) but thankfully that doesn't
# seem to come up in DDL queries.

_encoding_compat = {
_encoding_compat: dict[Optional[str], str] = {
# this dict should be [str, str] but mypy will not allow to call
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

value = '$."%s"' % value
return value
formatted_value = '$."%s"' % value
return formatted_value
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

# override to return True, this is a native type, just turning
# off native_uuid for internal data handling
return True

def bind_processor(self, dialect):
def bind_processor(self, dialect: MariaDBDialect) -> Optional[_BindProcessorType[_UUID_RETURN]]: # type: ignore[override] # noqa: E501
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@@ -120,21 +151,26 @@ class MySQLDialect_mysqlconnector(MySQLDialect):

execution_ctx_cls = MySQLExecutionContext_mysqlconnector

preparer = MySQLIdentifierPreparer_mysqlconnector
preparer: type[MySQLIdentifierPreparer] = (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

def parse(self, show_create, charset):
def parse(
self, show_create: str, charset: Optional[str]
) -> ReflectedState:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@@ -379,7 +409,9 @@ def _describe_to_create(self, table_name, columns):
]
)

def _parse_keyexprs(self, identifiers):
def _parse_keyexprs(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

let's see if it still passes typecheck

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@@ -1345,6 +1405,7 @@ def _render_json_extract_from_binary(self, binary, operator, **kw):
)
)
elif binary.type._type_affinity in (sqltypes.Numeric, sqltypes.Float):
binary.type = cast(sqltypes.Numeric[Any], binary.type)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

pyproject.toml Outdated
@@ -46,7 +46,9 @@ Discussions = "https://github.com/sqlalchemy/sqlalchemy/discussions"
asyncio = ["greenlet>=1"]
mypy = [
"mypy >= 1.7",
"types-greenlet >= 2"
"types-greenlet >= 2",
"types-PyMySQL >=1.1",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

Done

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@Polandia94
Copy link
Contributor Author

@CaselIT I think with your last patchset all comments are solved and is passing the tests. Let me know if you need that i change something on the PR

@CaselIT
Copy link
Member

CaselIT commented Apr 28, 2025

yes, it should be done. I'm waiting for a review from mike. We should be able to merge it soonish

@sqla-tester
Copy link
Collaborator

Michael Bayer (zzzeek) wrote:

can we backport to 2.0.x? it will be impossible to do MySQL changes otherwise

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@sqla-tester
Copy link
Collaborator

Federico Caselli (CaselIT) wrote:

I planned to do that after it was done. Will do later today

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Tipyng of mysql dialect.

possible breaking changes:

- on `visit_sequence`, `visit_true` and `visit_false` I changed the param names to be the same tht in the super class.
- Removed  `tostring` on `array`. `tostring` is deprecated since Python 3.2 and removed in Python3.9 so i guess we can remove that option altogheter.
- create_connect_args on aiomysql, added an unused param _translate_args, only to have same signature as super class.
-  delete _check_unicode_returns method. on MySQLDialect_mysqldb. I think is not used after https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/1946, and is calling to a super that I think doesnt exist anymore.
- delete _set_isolation_level, is unused, and has a super that doesnt exists anymore:
sqlalchemy@af1b916
- Separate _bitmap in enumerated to _bitmap and _inversed_bitmap to have type safety
- Add inheritance from log.Identified to MySQLTableDefinitionParser, because has the decorathor @log.class_logger

Related to issue :
sqlalchemy#6810

Closes: sqlalchemy#12164
Pull-request: sqlalchemy#12164
Pull-request-sha: b877cca

Change-Id: I37bd98049ff1a64d58e9490b0e5e2ea764dd1f73
Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Michael Bayer (zzzeek) wrote:

if this change is local to gerrit now and we can iterate here, I want to go through and change most of the use of third party names like MySQLdb.Connection and replace with protocols DBAPIConnection, etc., that's what these are for. we can use cast() as needed when we need a specific method, but otherwise the patch here is very dependent on lots and lots of third party classes that typically aren't typed, could change names (and have awkward names anyway), the code is not as easy to follow as the main advantage to typing is understanding the signature of functions. using consistent types all the way through using protocols will make this much more clear and the code is more robust for subclassing, etc.

i can do this locally if we are in a gerrit iteration now.

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

return __import__("MySQLdb")

def on_connect(self):
def on_connect(self) -> Callable[["MySQLdb.Connection"], None]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Michael Bayer (zzzeek) wrote:

i dont think this is the approach we should be taking here, trying to get a handle on specific types inside the DBAPIs that typically don't have stubs. We have protocols for DBAPI connection, cursor DBAPIConnection, DBAPICursor and thats what should be used here. I also note that if we go back to engine/interfaces engine/default the callable here has Any in it, that should be DBAPIConnection etc.

here's how this can be done for this method, for example, including interfaces / default. it passes mypy 100%

diff --git a/lib/sqlalchemy/dialects/mysql/mysqldb.py b/lib/sqlalchemy/dialects/mysql/mysqldb.py
index ae955389e..a6780f94b 100644
--- a/lib/sqlalchemy/dialects/mysql/mysqldb.py
+++ b/lib/sqlalchemy/dialects/mysql/mysqldb.py
@@ -89,7 +89,7 @@ from __future__ import annotations
 
 import re
 from types import ModuleType
-from typing import Any
+from typing import Any, cast
 from typing import Callable
 from typing import Iterable
 from typing import Literal
@@ -164,14 +164,14 @@ class MySQLDialect_mysqldb(MySQLDialect):
     def import_dbapi(cls) -> ModuleType:
         return __import__("MySQLdb")
 
-    def on_connect(self) -> Callable[[MySQLdb.Connection], None]:
+    def on_connect(self) -> Callable[[DBAPIConnection], None]:
         super_ = super().on_connect()
 
-        def on_connect(conn: MySQLdb.Connection) -> None:
+        def on_connect(conn: DBAPIConnection) -> None:
             if super_ is not None:
                 super_(conn)
 
-            charset_name = conn.character_set_name()
+            charset_name = cast(MySQLdb.Connection, conn).character_set_name()
 
             if charset_name is not None:
                 cursor = conn.cursor()
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 45c00fe0e..ac3048b6b 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -563,7 +563,7 @@ class DefaultDialect(Dialect):
                 % (self.label_length, self.max_identifier_length)
             )
 
-    def on_connect(self) -> Optional[Callable[[Any], None]]:
+    def on_connect(self) -> Optional[Callable[[DBAPIConnection], None]]:
         # inherits the docstring from interfaces.Dialect.on_connect
         return None
 
diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py
index 556e49d7f..7a6c4005e 100644
--- a/lib/sqlalchemy/engine/interfaces.py
+++ b/lib/sqlalchemy/engine/interfaces.py
@@ -2307,7 +2307,7 @@ class Dialect(EventTarget):
         """
         return self.on_connect()
 
-    def on_connect(self) -> Optional[Callable[[Any], None]]:
+    def on_connect(self) -> Optional[Callable[[DBAPIConnection], None]]:
         """return a callable which sets up a newly created DBAPI connection.
 
         The callable should accept a single argument "conn" which is the

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@zzzeek
Copy link
Member

zzzeek commented May 9, 2025

I see you did those changes thanks! ( I was going to do them) - is this PR in sync with the gerrit we have? I can re-push from here into gerrit but I dont want to lose changes that @CaselIT may have made in gerrit only

@sqla-tester
Copy link
Collaborator

Pablo Nicolás Estevez (Polandia94) wrote:

I created a new commit on github, with this approach to pyodbc, pymysql and aiomysql, is in the PR branch.

I find it simplier to check the diff on github here:
https://github.com/Polandia94/sqlalchemy/pull/1/files

If this is the approach you are looking for I can change the next of the modules next week.

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@zzzeek
Copy link
Member

zzzeek commented May 9, 2025

here is the problem. we have been editing this patch in gerrit for weeks, see https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829/3..8

can you first grab the full state of the gerrit from the latest here:

git fetch https://gerrit.sqlalchemy.org/sqlalchemy/sqlalchemy refs/changes/29/5829/8 && git checkout FETCH_HEAD

that's the codebase to then make subsequent changes on top of

sorry for not being clear that it looked like we were working on this patch internally at this point (you are of course welcome to keep contributing! just we need to have the gitub PR here up to date)

@sqla-tester
Copy link
Collaborator

Pablo Nicolás Estevez (Polandia94) wrote:

hi, I don't know how to use Gerrit.
I created a new cmmit with this changes over the last patch and pushed to my PR on github.
#12164

I have to froce-push to reconcile history, left the all history on https://github.com/Polandia94/sqlalchemy/tree/type-mysql-backup

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

@zzzeek zzzeek requested a review from sqla-tester May 13, 2025 13:39
Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 545e2c3 of this pull request into gerrit so we can run tests and reviews and stuff

@sqla-tester
Copy link
Collaborator

Patchset 545e2c3 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federico Caselli (CaselIT) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5875

  • lib/sqlalchemy/dialects/mysql/base.py (line 3444): it's likely fine since it's a string anyway due to future-annotation but it's likely better to restore the uppercase if we do another change

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Michael Bayer (zzzeek) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5875

  • lib/sqlalchemy/dialects/mysql/base.py (line 3444): OK, there's tons of lowercase[foo] in this particular cherry pick, none of it causes a problem because we dont run mypy under 3.9. will try to get most of them

OK I changed a few hundred of them

@sqla-tester
Copy link
Collaborator

Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5829 has been merged. Congratulations! :)

@sqla-tester
Copy link
Collaborator

Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5875 has been merged. Congratulations! :)

sqlalchemy-bot pushed a commit that referenced this pull request May 20, 2025
Closes: #12164
Pull-request: #12164
Pull-request-sha: 545e2c3
Co-authored-by: Mike Bayer <[email protected]>
Change-Id: I37bd98049ff1a64d58e9490b0e5e2ea764dd1f73
(cherry picked from commit d89db542e419ac83ce1a43a5c2bf3c8225d6d2e9)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants