-
-
Notifications
You must be signed in to change notification settings - Fork 13
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
fix optimize_expression to genereate atlas of feature with textual PKs #72
Open
maxencelaurent
wants to merge
3
commits into
3liz:master
Choose a base branch
from
maxencelaurent:fix-string-pkeys
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -312,17 +312,18 @@ def optimize_expression(layer, expression): | |||||||||
logger.info("'$id' not found in the expression, returning the input expression.") | ||||||||||
return expression | ||||||||||
|
||||||||||
# extract indexes of primary keys | ||||||||||
primary_keys = layer.primaryKeyAttributes() | ||||||||||
if len(primary_keys) != 1: | ||||||||||
logger.info("Primary keys are not defined in the layer '{}'.".format(layer.id())) | ||||||||||
return expression | ||||||||||
|
||||||||||
field = layer.fields().at(0) | ||||||||||
if not field.isNumeric(): | ||||||||||
logger.info("The field '{}' is not numeric in layer '{}'.".format(field.name(), layer.id())) | ||||||||||
return expression | ||||||||||
# extract primary key from fields list | ||||||||||
pk_index = primary_keys[0] | ||||||||||
pk_field = layer.fields().at(pk_index) | ||||||||||
|
||||||||||
expression = expression.replace('$id', '"{}"'.format(field.name())) | ||||||||||
logger.info('$id has been replaced by "{}" in layer "{}"'.format(field.name(), layer.id())) | ||||||||||
# replace `$id` with effective PK name | ||||||||||
expression = expression.replace('$id', '"{}"'.format(pk_field.name())) | ||||||||||
logger.info('$id has been replaced by "{}" in layer "{}"'.format(pk_field.name(), layer.id())) | ||||||||||
Comment on lines
+326
to
+327
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.
Suggested change
Let's switch to fstrings now at the same time |
||||||||||
|
||||||||||
return expression |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 your proposal. I am not sure to understand correctly the context you are targeting with this PR.
It seems to me
$id
will always return an integer, the internal layer feature ID, which:For example,
$id
will return the value ofid_integer_pk
for this layer:but will not return the value of
id_text_pk
for this layer, but 1 or 2:Can you please share a QGIS project with an example layer (FlatGeoBuf, GeoJSON, etc.), so that we can test it on real data ?
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.
Hi @mdouchin
Please find some data here: https://github.com/maxencelaurent/qgis-atlasprint-issue-71
As you mentioned, there are two cases:
In the first one, QGIS is able to retrieve the PK from existing fields. Thus,
layer.primaryKeyAttributes()
returns the list of indices of the fields that make up the PK. LWC use this information to build the GetPrintAtlas queries:EXP_FILTER="$id IN ('68ca5ce1-7ac4-4fbe-9a76-3c0d3d41fa53')"
Under some circumstances (eg. postgresql), such a field may be of type UUID. This behaviour almost only exists for postgresql layers. I couldn't reproduce it with sqlite for example.
In the second one, QGIS is not able to retrieve the PK from existing fields. Hence, it uses an internal
$id
field which is always of type integer.layer.primaryKeyAttributes()
always returns an empty list. LWC uses this@id
to build the query :EXP_FILTER="$id IN (1)"
.On the atlas-plugin side, the EXP_FILTER is optimized. The purpose of this optimization is to replace the
$id
with the effective field name of the PK.The plugin verifies that :
If both tests are true, the filter is optimized :
$id
is replaced with the name of the first field.In my data, you'll find some layers:
text_pk_first_place & text_pk_sec_place
$id
is used.int_pk_first_place
int_pk_sec_place
uuid_pk_first_place & uuid_pk_sec_place
$id
is used.int_pk_sec_place_but_other_int_first
psql_uuid