-
-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
Add DB-API 2.0 cursor support to pandas DataFrame constructor data
parameter
#54376
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,6 +131,42 @@ def shape(self): | |
return self._values.shape | ||
|
||
|
||
class MockDBCursor: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need this or can we just set up a test that assigns this to the cursor? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what you mean, but I could drop this specific of a test and add a test with the rest of the database tests. That would be more of a real-world use of the feature. |
||
""" | ||
A class which is cursor-like but not actually a database cursor | ||
|
||
This mock class includes an iterator interface. This technically is not | ||
required by the DB-API 2.0, but many database interfaces include | ||
this feature. This cursor object is intended to mock that behavior. | ||
|
||
""" | ||
|
||
def __iter__(self) -> Iterator: | ||
return iter(self.fetchall()) | ||
|
||
@property | ||
def description(self): | ||
return [ | ||
("First", 0, None, None, None, None, False), | ||
("Second", 0, None, None, None, None, False), | ||
("Third", 1, None, None, None, None, True), | ||
("Fourth", 2, None, None, None, None, True), | ||
] | ||
|
||
@property | ||
def rowcount(self): | ||
return 1 | ||
|
||
def execute(self, *args): | ||
return | ||
|
||
def fetchall(self): | ||
return [("a", "b", 1.2, 3)] | ||
|
||
def close(self): | ||
return | ||
|
||
|
||
# collect all objects to be tested for list-like-ness; use tuples of objects, | ||
# whether they are list-like or not (special casing for sets), and their ID | ||
ll_params = [ | ||
|
@@ -184,6 +220,7 @@ def shape(self): | |
(object(), False, "object"), | ||
(np.nan, False, "NaN"), | ||
(None, False, "None"), | ||
(MockDBCursor(), True, "duck-db-cursor"), | ||
] | ||
objs, expected, ids = zip(*ll_params) | ||
|
||
|
@@ -1985,3 +2022,19 @@ def test_ensure_int32(): | |
values = np.arange(10, dtype=np.int64) | ||
result = ensure_int32(values) | ||
assert result.dtype == np.int32 | ||
|
||
|
||
def test_is_cursor(): | ||
is_cursor = inference.is_cursor | ||
|
||
cur = MockDBCursor() | ||
|
||
assert inference.is_list_like(cur) | ||
assert is_cursor(cur) | ||
|
||
arr = MockNumpyLikeArray([[0, 1]]) | ||
|
||
assert not is_cursor(arr) | ||
assert not is_cursor("") | ||
assert not is_cursor(1) | ||
assert not is_cursor(1.23) |
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 just move this to the sql.py file itself; I don't think this would be used elsewhere
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 intent is that it would be used by the
DataFrame
constructor after seeing if thedata
is list-like (seepandas/core/frame.py
diff). I realize that is a bit invasive for such a special case, but it's the place where it is most generally useful for this use-case.